home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianVisWindows.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  90KB  |  3,368 lines

  1. /*ScianVisWindows.c
  2.   Visualization window stuff
  3.   Eric Pepke
  4.   April 6, 1990
  5. */
  6.  
  7. #include "Scian.h"
  8. #include "ScianTypes.h"
  9. #include "ScianArrays.h"
  10. #include "ScianLists.h"
  11. #include "ScianWindows.h"
  12. #include "ScianTextBoxes.h"
  13. #include "ScianTitleBoxes.h"
  14. #include "ScianObjWindows.h"
  15. #include "ScianIcons.h"
  16. #include "ScianColors.h"
  17. #include "ScianControls.h"
  18. #include "ScianButtons.h"
  19. #include "ScianSpaces.h"
  20. #include "ScianLights.h"
  21. #include "ScianSliders.h"
  22. #include "ScianIDs.h"
  23. #include "ScianVisWindows.h"
  24. #include "ScianDatasets.h"
  25. #include "ScianPictures.h"
  26. #include "ScianDialogs.h"
  27. #include "ScianEvents.h"
  28. #include "ScianScripts.h"
  29. #include "ScianErrors.h"
  30. #include "ScianMethods.h"
  31. #include "ScianStyle.h"
  32. #include "ScianVisObjects.h"
  33. #include "ScianDraw.h"
  34. #include "ScianDrawings.h"
  35. #include "ScianObjFunctions.h"
  36. #include "ScianFilters.h"
  37. #include "ScianPick.h"
  38. #include "ScianSymbols.h"
  39. #include "ScianTemplates.h"
  40. #include "ScianTemplateHelper.h"
  41.  
  42. ObjPtr visWindowClass;            /*Class for vis windows*/
  43. ObjPtr spaceWindowClass;        /*Class for space subwindows*/
  44. ObjPtr visCorralClass;            /*Class for corral of a vis window*/
  45. Bool showControlPanels = true;        /*True iff show control panels by default*/
  46. ObjPtr visualizeAsList;            /*List for Visualize As*/
  47.  
  48. static ObjPtr HideVisWindowPanel(window)
  49. WinInfoPtr window;
  50. /*Hides the panel of the controls on the vis window.  Returns true iff it did*/
  51. {
  52.  
  53.     if (window)
  54.     {
  55.     ObjPtr panel, space, assocPanel;
  56.     WinInfoPtr subWindow;
  57.     int panelWidth;
  58.     int left, right, bottom, top;
  59.     int nl, nr, nb, nt;
  60.  
  61.     ImInvalid((ObjPtr) window);
  62.  
  63.     SelWindow(window);
  64.     GetWindowBounds(&left, &right, &bottom, &top);
  65.  
  66.     space = FindSpace(window);
  67.  
  68.         if (!space)
  69.     {
  70.         return false;
  71.     }
  72.  
  73.     panel = GetVar(space, OBJPANEL);
  74.     if (panel)
  75.     {
  76.         /*Get the panel's bounds*/
  77.         Get2DIntBounds(panel, &nl, &nr, &nb, &nt); 
  78.         panelWidth = nr - nl;
  79.  
  80.         /*Change panel to be off the screen*/
  81.         nl = right + 1;
  82.         nr = nl + panelWidth;
  83.         Set2DIntBounds(panel, nl, nr, nb, nt);
  84.         ImInvalid(panel);
  85.     }
  86.  
  87.     panel = GetVar(space, TOOLPANEL);
  88.     if (panel)
  89.     {
  90.         /*Get the panel's bounds*/
  91.         Get2DIntBounds(panel, &nl, &nr, &nb, &nt); 
  92.         panelWidth = nr - nl;
  93.  
  94.         /*Change panel to be off the screen*/
  95.         nr = left - 1;
  96.         nl = nr - panelWidth;
  97.         Set2DIntBounds(panel, nl, nr, nb, nt);
  98.         ImInvalid(panel);
  99.     }
  100.  
  101.     /*Change the window or space*/
  102.     Get2DIntBounds(space, &nl, &nr, &nb, &nt); 
  103.     nr = right;
  104.     nl = left;
  105.  
  106.     if ((subWindow = (WinInfoPtr) GetVar((ObjPtr) window, SPACEWINDOW)) &&
  107.         subWindow != window)
  108.     {
  109.         /*Change the window*/
  110.         int ox, oy;
  111.         SelWindow(window);
  112.         GetWindowOrigin(&ox, &oy);
  113.         SelWindow(subWindow);
  114.         SetWindowPosition(ox, ox + nr - nl, oy, oy + nt - nb);
  115.     }
  116.     else
  117.     {
  118.         /*Change the space*/
  119.         Set2DIntBounds(space, nl, nr, nb, nt);
  120.     
  121.         ImInvalid(space);
  122.  
  123.         /*And its panels*/
  124.         assocPanel = GetVar(space, FRONTPANEL);
  125.         if (assocPanel)
  126.         {
  127.         int ol, or, ob, ot;
  128.  
  129.         Get2DIntBounds(assocPanel, &ol, &or, &ob, &ot);
  130.         ReshapeObject(assocPanel, ol, or, ob, ot, nl, nr, nb, nt);
  131.         ImInvalid(assocPanel);
  132.         }
  133.  
  134.         assocPanel = GetVar(space, BACKPANEL);
  135.         if (assocPanel)
  136.         {
  137.         int ol, or, ob, ot;
  138.  
  139.         Get2DIntBounds(assocPanel, &ol, &or, &ob, &ot);
  140.         ReshapeObject(assocPanel, ol, or, ob, ot, nl, nr, nb, nt);
  141.         ImInvalid(assocPanel);
  142.         }
  143.     }
  144.  
  145.     SetVar((ObjPtr) window, PANELHIDDEN, ObjTrue);
  146.  
  147.     return ObjTrue;
  148.     }
  149.     else
  150.     {
  151.     return ObjFalse;
  152.     }
  153. }
  154.  
  155. void DoHidePanel()
  156. {
  157.     if (selWinInfo)
  158.     {
  159.     if (logging)
  160.     {
  161.         Log("hide panel\n");
  162.     }
  163.  
  164.     DeferMessage((ObjPtr) selWinInfo, HIDEPANEL);
  165.     }
  166. }
  167.  
  168. static ObjPtr ShowVisWindowPanel(window)
  169. WinInfoPtr window;
  170. /*Shows the panel of the controls on the vis window.  Returns true iff it did*/
  171. {
  172.     if (window)
  173.     {
  174.     ObjPtr panel, space, assocPanel;
  175.     WinInfoPtr subWindow;
  176.     int lPanelWidth, rPanelWidth;
  177.     int left, right, bottom, top;
  178.     int nl, nr, nb, nt;
  179.  
  180.     ImInvalid((ObjPtr) window);
  181.  
  182.     SelWindow(window);
  183.     GetWindowBounds(&left, &right, &bottom, &top);
  184.  
  185.     space = FindSpace(window);
  186.  
  187.         if (!space)
  188.     {
  189.         return false;
  190.     }
  191.  
  192.     panel = GetVar(space, OBJPANEL);
  193.     if (panel)
  194.     {
  195.         /*Get the panel's bounds*/
  196.         Get2DIntBounds(panel, &nl, &nr, &nb, &nt); 
  197.         rPanelWidth = nr - nl;
  198.  
  199.         /*Change panel to be on the screen*/
  200.         nr = right;
  201.         nl = right - rPanelWidth;
  202.         Set2DIntBounds(panel, nl, nr, nb, nt);
  203.         ImInvalid(panel);
  204.     }
  205.  
  206.     panel = GetVar(space, TOOLPANEL);
  207.     if (panel)
  208.     {
  209.         /*Get the panel's bounds*/
  210.         Get2DIntBounds(panel, &nl, &nr, &nb, &nt); 
  211.         lPanelWidth = nr - nl;
  212.  
  213.         /*Change panel to be on the screen*/
  214.         nl = left;
  215.         nr = left + lPanelWidth;
  216.         Set2DIntBounds(panel, nl, nr, nb, nt);
  217.         ImInvalid(panel);
  218.     }
  219.  
  220.     /*Change the window or space*/
  221.     Get2DIntBounds(space, &nl, &nr, &nb, &nt); 
  222.     nr = right - rPanelWidth;
  223.     nl = left + lPanelWidth;
  224.  
  225.     if ((subWindow = (WinInfoPtr) GetVar((ObjPtr) window, SPACEWINDOW)) &&
  226.         subWindow != window)
  227.     {
  228.         /*Change the window*/
  229.         int ox, oy;
  230.         SelWindow(window);
  231.         GetWindowOrigin(&ox, &oy);
  232.         SelWindow(subWindow);
  233.         SetWindowPosition(ox, ox + nr - nl, oy, oy + nt - nb);
  234.     }
  235.     else
  236.     {
  237.         /*Change the space*/
  238.         Set2DIntBounds(space, nl, nr, nb, nt);
  239.  
  240.         ImInvalid(space);
  241.  
  242.         /*And its panels*/
  243.         assocPanel = GetVar(space, FRONTPANEL);
  244.         if (assocPanel)
  245.         {
  246.         int ol, or, ob, ot;
  247.  
  248.         Get2DIntBounds(assocPanel, &ol, &or, &ob, &ot);
  249.         ReshapeObject(assocPanel, ol, or, ob, ot, nl, nr, nb, nt);
  250.         ImInvalid(assocPanel);
  251.         }
  252.  
  253.         assocPanel = GetVar(space, BACKPANEL);
  254.         if (assocPanel)
  255.         {
  256.         int ol, or, ob, ot;
  257.  
  258.         Get2DIntBounds(assocPanel, &ol, &or, &ob, &ot);
  259.         ReshapeObject(assocPanel, ol, or, ob, ot, nl, nr, nb, nt);
  260.         ImInvalid(assocPanel);
  261.         }
  262.     }
  263.  
  264.     SetVar((ObjPtr) window, PANELHIDDEN, ObjFalse);
  265.  
  266.     return ObjTrue;
  267.     }
  268.     else
  269.     {
  270.     return ObjFalse;
  271.     }
  272. }
  273.  
  274. void DoShowPanel()
  275. {
  276.     if (selWinInfo)
  277.     {
  278.     if (logging)
  279.     {
  280.         Log("show panel\n");
  281.     }
  282.  
  283.     DeferMessage((ObjPtr) selWinInfo, SHOWPANEL);
  284.     }
  285. }
  286.  
  287. int annotStagger = 0;
  288.  
  289. ObjPtr DeleteSpacePanelText(text)
  290. ObjPtr text;
  291. /*Delete text from a space panel*/
  292. {
  293.     return ObjTrue;
  294. }
  295.  
  296. void AddAnnotation(name, bounds)
  297. char *name;
  298. real bounds[4];
  299. /*Adds annotation with name and bounds to current window*/
  300. {
  301.     if (selWinInfo)
  302.     {
  303.     /*Search for a space*/
  304.     ObjPtr space, frontPanel;
  305.  
  306.     space = FindSpace(selWinInfo);
  307.  
  308.     if (space)
  309.     {
  310.         frontPanel = GetObjectVar("AddAnnotation", space, FRONTPANEL);
  311.         if (frontPanel)
  312.         {
  313.         /*There's a front panel.  Stick an annotation there*/
  314.         ObjPtr annotation;
  315.  
  316.  
  317.         ++nAnnot;
  318.         annotation = NewTextBox((int) bounds[0], (int) bounds[1], (int) bounds[2], (int) bounds[3],
  319.                     /*WITH_BG + */EDITABLE + ADJUSTABLE, name, "");
  320.  
  321.         SetMethod(annotation, CLONE, CloneAnnotation);
  322.         SetMethod(annotation, DUPLICATE, DuplicateDrawing);
  323.         PrefixList(GetVar(frontPanel, CONTENTS), annotation);
  324.         SetVar(annotation, PARENT, frontPanel);
  325.         SetTextColor(annotation, NewInt(UIWHITE));
  326.         ImInvalid(annotation);
  327.         SetTextFont(annotation, ANNOTFONT);
  328.         SetTextSize(annotation, ANNOTFONTSIZE);
  329.         SetVar(annotation, STICKINESS, NewInt(FLOATINGLEFT + FLOATINGRIGHT + FLOATINGTOP + FLOATINGBOTTOM));
  330.         SetMethod(annotation, DELETEICON, DeleteSpacePanelText);
  331.         SetMethod(annotation, DELETE, DeleteObject); 
  332.         SetMethod(annotation, PUSHTOBOTTOM, PushDrawingToBottom);
  333.         SetMethod(annotation, BRINGTOTOP, BringDrawingToTop);
  334.         SetMethod(annotation, MOVETOBACKPANEL, MoveDrawingToBackPanel);
  335.         SetMethod(annotation, MOVETOFRONTPANEL, MoveDrawingToFrontPanel);
  336.  
  337.         DeselectAll();
  338.         Select(annotation, true);
  339.         MakeMeCurrent(annotation);
  340.  
  341.         if (logging)
  342.         {
  343.             /*Log the action.*/
  344.             char cmd[256];
  345.             char *d;
  346.  
  347.             d = &(cmd[0]);
  348.             sprintf(cmd, "annotation ");
  349.             while (*d) ++d;
  350.             MakeObjectName(d, annotation);
  351.             while (*d) ++d;
  352.             sprintf(d, " [%g %g %g %g]\n",
  353.             bounds[0], bounds[1], bounds[2], bounds[3]);
  354.             Log(cmd);
  355.         }
  356.         }
  357.     }
  358.     }
  359. }
  360.  
  361. void AddTimeReadout(name, bounds)
  362. char *name;
  363. real bounds[4];
  364. /*Adds annotation with name and bounds to current window*/
  365. {
  366.     if (selWinInfo)
  367.     {
  368.     /*Search for a space*/
  369.     ObjPtr space, frontPanel, list;
  370.  
  371.     space = FindSpace(selWinInfo);
  372.  
  373.     if (space)
  374.     {
  375.         frontPanel = GetObjectVar("AddTimeReadout", space, FRONTPANEL);
  376.         if (frontPanel)
  377.         {
  378.         /*There's a front panel.  Stick a time readout there*/
  379.         ObjPtr timeReadout;
  380.  
  381.         ++nTimeReadout;
  382.         timeReadout = NewTimeReadout((int) bounds[0], (int) bounds[1], (int) bounds[2], (int) bounds[3],
  383.                     name, space);
  384.         SetMethod(timeReadout, CLONE, CloneTimeReadout);
  385.         SetMethod(timeReadout, DUPLICATE, DuplicateDrawing);
  386.         PrefixList(GetVar(frontPanel, CONTENTS), timeReadout);
  387.         SetVar(timeReadout, PARENT, frontPanel);
  388.         SetTextColor(timeReadout, NewInt(UIWHITE));
  389.         ImInvalid(timeReadout);
  390.         SetTextFont(timeReadout, ANNOTFONT);
  391.         SetTextSize(timeReadout, ANNOTFONTSIZE);
  392.         SetVar(timeReadout, STICKINESS, NewInt(FLOATINGLEFT + FLOATINGRIGHT + FLOATINGTOP + FLOATINGBOTTOM));
  393.         SetMethod(timeReadout, DELETEICON, DeleteSpacePanelText);
  394.         SetMethod(timeReadout, DELETE, DeleteObject); 
  395.         SetMethod(timeReadout, PUSHTOBOTTOM, PushDrawingToBottom);
  396.         SetMethod(timeReadout, BRINGTOTOP, BringDrawingToTop);
  397.         SetMethod(timeReadout, MOVETOBACKPANEL, MoveDrawingToBackPanel);
  398.         SetMethod(timeReadout, MOVETOFRONTPANEL, MoveDrawingToFrontPanel);
  399.         list = NewList();
  400.         PrefixList(list, NewSymbol(BOUNDS));
  401.         PrefixList(list, NewSymbol(TEXTFONT));
  402.         PrefixList(list, NewSymbol(TEXTSIZE));
  403.         PrefixList(list, NewSymbol(ALIGNMENT));
  404.         SetVar(timeReadout, SNAPVARS, list);
  405.  
  406.         DeselectAll();
  407.         Select(timeReadout, true);
  408.  
  409.         if (logging)
  410.         {
  411.             /*Log the action.*/
  412.             char cmd[256];
  413.             char *d;
  414.  
  415.             d = &(cmd[0]);
  416.             sprintf(cmd, "timereadout ");
  417.             while (*d) ++d;
  418.             MakeObjectName(d, timeReadout);
  419.             while (*d) ++d;
  420.             sprintf(d, " [%g %g %g %g]\n",
  421.             bounds[0], bounds[1], bounds[2], bounds[3]);
  422.             Log(cmd);
  423.         }
  424.         }
  425.     }
  426.     }
  427. }
  428.  
  429. void AddRectangle(name, bounds)
  430. char *name;
  431. real bounds[4];
  432. /*Adds rectangle with name and bounds to current window*/
  433. {
  434.     if (selWinInfo)
  435.     {
  436.     /*Search for a space*/
  437.     ObjPtr space, frontPanel;
  438.  
  439.     space = FindSpace(selWinInfo);
  440.  
  441.     if (space)
  442.     {
  443.         frontPanel = GetObjectVar("AddRectangle", space, FRONTPANEL);
  444.         if (frontPanel)
  445.         {
  446.         /*There's a front panel.  Stick a rectangle there*/
  447.         ObjPtr rectangle;
  448.  
  449.         ++nRect;
  450.         rectangle = NewRectangle((int) bounds[0], (int) bounds[1], (int) bounds[2], (int) bounds[3],
  451.                     name);
  452.         PrefixList(GetVar(frontPanel, CONTENTS), rectangle);
  453.         SetVar(rectangle, PARENT, frontPanel);
  454.         ImInvalid(rectangle);
  455.  
  456.         DeselectAll();
  457.         Select(rectangle, true);
  458.  
  459.         if (logging)
  460.         {
  461.             /*Log the action.*/
  462.             char cmd[256];
  463.             char *d;
  464.  
  465.             d = &(cmd[0]);
  466.             sprintf(cmd, "rectangle ");
  467.             while (*d) ++d;
  468.             MakeObjectName(d, rectangle);
  469.             while (*d) ++d;
  470.             sprintf(d, " [%g %g %g %g]\n",
  471.             bounds[0], bounds[1], bounds[2], bounds[3]);
  472.             Log(cmd);
  473.         }
  474.         }
  475.     }
  476.     }
  477. }
  478.  
  479. void AddLine(name, x1, y1, x2, y2)
  480. char *name;
  481. int x1, y1, x2, y2;
  482. /*Adds line with name and endpoints (x1, y1)-(x2, y2) to current window*/
  483. {
  484.     if (selWinInfo)
  485.     {
  486.     /*Search for a space*/
  487.     ObjPtr space, frontPanel;
  488.  
  489.     space = FindSpace(selWinInfo);
  490.  
  491.     if (space)
  492.     {
  493.         frontPanel = GetObjectVar("AddLine", space, FRONTPANEL);
  494.         if (frontPanel)
  495.         {
  496.         /*There's a front panel.  Stick a line there*/
  497.         ObjPtr line;
  498.  
  499.         ++nLine;
  500.         line = NewLine(x1, y1, x2, y2, name);
  501.         PrefixList(GetVar(frontPanel, CONTENTS), line);
  502.         SetVar(line, PARENT, frontPanel);
  503.         ImInvalid(line);
  504.  
  505.         DeselectAll();
  506.         Select(line, true);
  507.  
  508.         if (logging)
  509.         {
  510.             /*Log the action.*/
  511.             char cmd[256];
  512.             char *d;
  513.  
  514.             d = &(cmd[0]);
  515.             sprintf(cmd, "line ");
  516.             while (*d) ++d;
  517.             MakeObjectName(d, line);
  518.             while (*d) ++d;
  519.             sprintf(d, " %d %d %d %d\n",
  520.             x1, y1, x2, y2);
  521.             Log(cmd);
  522.         }
  523.         }
  524.     }
  525.     }
  526. }
  527.  
  528. static void DoTogglePanel()
  529. /*Toggles the panel of the controls on the top window.*/
  530. {
  531.     if (selWinInfo)
  532.     {
  533.     if (GetPredicate((ObjPtr) selWinInfo, PANELHIDDEN))
  534.     {
  535.         DoShowPanel();
  536.     }
  537.     else
  538.     {
  539.         DoHidePanel();
  540.     }
  541.     }
  542. }
  543.  
  544. void DoShowControls()
  545. /*Shows the controls in the selected objects in the window*/
  546. {
  547.     DoObjFunction(OF_SHOW_CONTROLS);
  548. }
  549.  
  550. ObjPtr MakeLocalCopy(object)
  551. ObjPtr object;
  552. /*Makes a local copy of an object*/
  553. {
  554.     object = ObjectWhichRepresents(selWinInfo, object);
  555.  
  556.     if (object && IsIcon(object))
  557.     {
  558.     ObjPtr repObj, newObj;
  559.     FuncTyp method;
  560.     
  561.     repObj = GetVar(object, REPOBJ);
  562.     if (repObj)
  563.     {
  564.         ObjPtr contentsList, corral = NULLOBJ;
  565.         contentsList = GetVar(object, PARENT);
  566.         if (contentsList || !IsList(contentsList))
  567.         {
  568.         contentsList = GetVar(contentsList, CONTENTS);
  569.         }
  570.         if (!contentsList || !IsList(contentsList))
  571.         {
  572.         ReportError("MakeLocalCopy","Internal error: cannot find contents list");
  573.         }
  574.  
  575.         if (contentsList)
  576.         {
  577.         corral = contentsList;
  578.         while (corral && !IsCorral(corral))
  579.         {
  580.             corral = GetVar(corral, PARENT);
  581.         }
  582.         }
  583.  
  584.         if (!corral)
  585.         {
  586.         ReportError("MakeLocalCopy", "Cannot find local corral");
  587.         }
  588.  
  589.         method = GetMethodSurely("MakeLocalCopy", repObj, CLONE);
  590.         if (!method)
  591.         {
  592.         return ObjFalse;
  593.         }
  594.  
  595.         method = GetMethod(object, DELETEICON);
  596.         if (method)
  597.         {
  598.         if (IsTrue((*method)(object)))
  599.         {
  600.             if (contentsList && IsList(contentsList))
  601.             {
  602.             ImInvalid(corral);
  603.             DeleteFromList(contentsList, object);
  604.             }
  605.         }
  606.         }
  607.  
  608.         method = GetMethod(repObj, CLONE);
  609.         if (method)
  610.         {
  611.         ObjPtr name;
  612.             newObj = (*method)(repObj);
  613.         object = Clone(object);
  614.             SetVar(object, REPOBJ, newObj);
  615.         MakeVar(newObj, NAME);
  616.         name = GetVar(newObj, NAME);
  617.         SetVar(object, NAME, object);
  618.         SetVar(object, SELECTED, ObjFalse);
  619.         }
  620.  
  621.         method = GetMethod(corral, DROPINCONTENTS);
  622.         if (method)
  623.         {
  624.         ObjPtr locArray;
  625.         int x, y;
  626.         real loc[2];
  627.         locArray = GetVar(object, ICONLOC);
  628.         if (locArray)
  629.         {
  630.             Array2CArray(loc, locArray);
  631.             x = loc[0];
  632.             y = loc[1];
  633.         }
  634.         else
  635.         {
  636.             x = y = 0;
  637.         }
  638.         (*method)(corral, object, x, y);
  639.         }
  640.         return ObjTrue;
  641.     }
  642.     }
  643.     return ObjFalse;
  644. }
  645.  
  646. ObjPtr DuplicateSpaceObject(object)
  647. ObjPtr object;
  648. /*Duplicates an individual object in the current window*/
  649. {
  650.     object = ObjectWhichRepresents(selWinInfo, object);
  651.     if (object && IsIcon(object))
  652.     {
  653.     ObjPtr repObj, newVis;
  654.     FuncTyp method;
  655.  
  656.     repObj = GetVar(object, REPOBJ);
  657.     if (repObj && !GetPredicate(repObj, ONEONLY))
  658.     {
  659.         ObjPtr corral = NULLOBJ;
  660.  
  661.         corral = GetVar(object, PARENT);
  662.  
  663.         if (corral)
  664.         {
  665.         while (corral && !IsCorral(corral))
  666.         {
  667.             corral = GetVar(corral, PARENT);
  668.         }
  669.         }
  670.  
  671.         if (!corral)
  672.         {
  673.         ReportError("DuplicateSpaceObject", "Cannot find local corral");
  674.         return ObjFalse;
  675.         }
  676.  
  677.         method = GetMethodSurely("DuplicateSpaceObject", repObj, CLONE);
  678.         if (!method)
  679.         {
  680.         return ObjFalse;
  681.         }
  682.  
  683.         newVis = (*method)(repObj);
  684.         SetVar(newVis, SELECTED, ObjFalse);
  685.         if (IsController(newVis))
  686.         {
  687.         AddControllerToSpace(newVis, FindSpace(selWinInfo), corral, NULLOBJ);
  688.         ImInvalid(newVis);
  689.         }
  690.         else
  691.         {
  692.         IdleAllWindows();
  693.         AddObjToSpace(newVis, FindSpace(selWinInfo), corral, NULLOBJ, NULLOBJ);
  694.         }
  695.         return ObjTrue;
  696.     }
  697.     }
  698.     return ObjFalse;
  699. }
  700.  
  701. int vwSerialNumber = 0;
  702.  
  703. void NewSerializedVisWindow()
  704. /*Creates a new, serialized visualization window*/
  705. {
  706.     WinInfoPtr visWindow;
  707.  
  708.     /*Create a vis window*/
  709.     sprintf(tempStr, "Visualization %d", ++vwSerialNumber); 
  710.     visWindow = NewVisWindow(tempStr, WINDBUF + WINZBUF + WINRGB);
  711. }
  712.  
  713.  
  714. int vawSerialNumber;
  715.  
  716. void DoShowFrontPanelControls()
  717. /*Shows the controls for the front panel in the selected vis window*/
  718. {
  719.     ObjPtr space, panel;
  720.     if (!selWinInfo)
  721.     {
  722.     return;
  723.     }
  724.  
  725.     space = FindSpace(selWinInfo);
  726.     if (!space)
  727.     {
  728.     return;
  729.     }
  730.  
  731.     panel = GetVar(space, FRONTPANEL);
  732.     if (!panel)
  733.     {
  734.     return;
  735.     }
  736.  
  737.     if (logging)
  738.     {
  739.     Log("show front panel controls\n");
  740.     InhibitLogging(true);
  741.     }
  742.     NewControlWindow(panel);
  743.     if (logging)
  744.     {
  745.     InhibitLogging(false);
  746.     }
  747. }
  748.  
  749. void DoShowBackPanelControls()
  750. /*Shows the controls for the back panel in the selected vis window*/
  751. {
  752.     ObjPtr space, panel;
  753.     if (!selWinInfo)
  754.     {
  755.     return;
  756.     }
  757.  
  758.     space = FindSpace(selWinInfo);
  759.     if (!space)
  760.     {
  761.     return;
  762.     }
  763.  
  764.     panel = GetVar(space, BACKPANEL);
  765.     if (!panel)
  766.     {
  767.     return;
  768.     }
  769.  
  770.     if (logging)
  771.     {
  772.     Log("show back panel controls\n");
  773.     InhibitLogging(true);
  774.     }
  775.  
  776.     NewControlWindow(panel);
  777.     if (logging)
  778.     {
  779.     InhibitLogging(false);
  780.     }
  781. }
  782.  
  783. void DoShowSpaceControls()
  784. /*Shows the controls for the space in the selected vis window*/
  785. {
  786.     ObjPtr space;
  787.     if (!selWinInfo)
  788.     {
  789.     return;
  790.     }
  791.  
  792.     space = FindSpace(selWinInfo);
  793.     if (!space)
  794.     {
  795.     return;
  796.     }
  797.  
  798.     if (logging)
  799.     {
  800.     Log("show space controls\n");
  801.     InhibitLogging(true);
  802.     }
  803.  
  804.     NewControlWindow(space);
  805.     if (logging)
  806.     {
  807.     InhibitLogging(false);
  808.     }
  809. }
  810.  
  811. static ObjPtr ShowFrontPanelControls()
  812. /*Shows the controls for the front panel in the selected vis window*/
  813. {
  814.     ObjPtr space, panel;
  815.     if (!selWinInfo)
  816.     {
  817.     return;
  818.     }
  819.  
  820.     space = FindSpace(selWinInfo);
  821.     if (!space)
  822.     {
  823.     return;
  824.     }
  825.  
  826.     panel = GetVar(space, FRONTPANEL);
  827.     if (!panel)
  828.     {
  829.     return;
  830.     }
  831.  
  832.     NewControlWindow(panel);
  833. }
  834.  
  835. static ObjPtr ShowBackPanelControls(win)
  836. ObjPtr win;
  837. /*Shows the controls for the back panel in the selected vis window*/
  838. {
  839.     ObjPtr space, panel;
  840.     if (!selWinInfo)
  841.     {
  842.     return;
  843.     }
  844.  
  845.     space = FindSpace(selWinInfo);
  846.     if (!space)
  847.     {
  848.     return;
  849.     }
  850.  
  851.     panel = GetVar(space, BACKPANEL);
  852.     if (!panel)
  853.     {
  854.     return;
  855.     }
  856.  
  857.     NewControlWindow(panel);
  858.  
  859.     return ObjTrue;
  860. }
  861.  
  862. static ObjPtr ShowSpaceControls(win)
  863. ObjPtr win;
  864. /*Shows the controls for the space in the selected vis window*/
  865. {
  866.     ObjPtr space;
  867.     if (!selWinInfo)
  868.     {
  869.     return;
  870.     }
  871.  
  872.     space = FindSpace(selWinInfo);
  873.     if (!space)
  874.     {
  875.     return;
  876.     }
  877.  
  878.     NewControlWindow(space);
  879.     return ObjTrue;
  880. }
  881.  
  882.  
  883. #define MINANNOTSIZE    40
  884. #define MINRECTSIZE    0
  885. #define MINLINESIZE    0
  886.  
  887. static ObjPtr DeleteClockReadout(readout)
  888. ObjPtr readout;
  889. /*Deletes a clock readout from a space*/
  890. {
  891.     return ObjTrue;
  892. }
  893.  
  894. static ObjPtr MakeClockValue(clockDisplay)
  895. ObjPtr clockDisplay;
  896. /*Makes the VALUE of a clock display*/
  897. {
  898.     ObjPtr space, timeObj, format;
  899.     real time;
  900.     char s[400];
  901.  
  902.     space = GetObjectVar("MakeClockValue", clockDisplay, SPACE);
  903.     if (!space)
  904.     {
  905.     return ObjFalse;
  906.     }
  907.  
  908.     MakeVar(space, TIME);
  909.     timeObj = GetVar(space, TIME);
  910.     if (!timeObj)
  911.     {
  912.     time = 0.0;
  913.     }
  914.     else
  915.     {
  916.     time = GetReal(timeObj);
  917.     }
  918.  
  919.     format = GetVar(clockDisplay, FORMAT);
  920.     if (format)
  921.     {
  922.     PrintClock(s, GetString(format), time);
  923.     }
  924.     else
  925.     {
  926.         sprintf(s, "%#.2f", time);
  927.     }
  928.  
  929.     SetVar(clockDisplay, VALUE, NewString(s));
  930.  
  931.     return ObjTrue;
  932. }
  933.  
  934. static ObjPtr ShowClockDisplayControls(display, windowName)
  935. ObjPtr display;
  936. char *windowName;
  937. /*Makes a new control window to control a clock display*/
  938. {
  939.     WinInfoPtr controlWindow;
  940.     ObjPtr var;
  941.     ObjPtr panel;
  942.     ObjPtr corral;
  943.     ObjPtr contents;
  944.     WinInfoPtr dialogExists;
  945.  
  946.     dialogExists = DialogExists((WinInfoPtr) display, NewString("Controls"));
  947.     controlWindow = GetDialog((WinInfoPtr) display, NewString("Controls"), windowName, 
  948.     CDWINWIDTH, CDWINHEIGHT, CDWINWIDTH,
  949.     CDWINHEIGHT, WINUI + WINFIXEDSIZE);
  950.     
  951.     if (!dialogExists)
  952.     {
  953.     long info;
  954.     ObjPtr value;
  955.     ObjPtr format;
  956.     ObjPtr checkBox, icon, name, colorBar, titleBox, textBox, button;
  957.     ObjPtr colorWheel, slider, radioGroup;
  958.     int left, right, bottom, top;
  959.  
  960.     SetVar((ObjPtr) controlWindow, REPOBJ, display);
  961.  
  962.     /*Set help string*/
  963.     SetVar((ObjPtr) controlWindow, HELPSTRING, NewString("This window \
  964. shows controls for a clock display.  For information about any of the controls \
  965. in the window, use Help In Context on the control.\n"));
  966.  
  967.     /*Add in a panel*/
  968.     panel = NewPanel(greyPanelClass, 0, CDWINWIDTH, 0, CDWINHEIGHT);
  969.     if (!panel)
  970.     {
  971.         return NULLOBJ;
  972.     }
  973.     contents = GetVar((ObjPtr) controlWindow, CONTENTS);
  974.     PrefixList(contents, panel);
  975.     SetVar(panel, PARENT, (ObjPtr) controlWindow);
  976.  
  977.     contents = GetVar(panel, CONTENTS);
  978.  
  979.     /*Add in the group of controls for text color*/
  980.     left = MINORBORDER;
  981.     top = CDWINHEIGHT - MINORBORDER;
  982.     right = left + 2 * MINORBORDER + 2 * MAJORBORDER + COLORWHEELWIDTH + SLIDERWIDTH;
  983.     
  984.     titleBox = NewTitleBox(left, right,
  985.             top - TITLEBOXTOP - MINORBORDER - 2 * MINORBORDER - COLORWHEELWIDTH
  986.                 - CHECKBOXHEIGHT - TEXTBOXHEIGHT - TEXTBOXSEP,
  987.             top, "Text");
  988.     SetVar(titleBox, PARENT, panel);
  989.     PrefixList(contents, titleBox);
  990.     left += MINORBORDER;
  991.     right -= MINORBORDER;
  992.     top -= TITLEBOXTOP + MINORBORDER;
  993.  
  994.     /*Make the color wheel*/
  995.     colorWheel = NewColorWheel(left, left + COLORWHEELWIDTH,
  996.             top - COLORWHEELWIDTH, top, "Text Color");
  997.     SetVar(colorWheel, PARENT, panel);
  998.     PrefixList(contents, colorWheel);
  999.     AssocColorControlWithVar(colorWheel, display, COLOR);
  1000.     SetVar(colorWheel, HELPSTRING, NewString("This color wheel controls the \
  1001. hue and saturation of the color used to draw the text in the clock display.  \
  1002. The final color is a combination of this hue and saturation and the value, or brightness, \
  1003. given by the Value slider."));
  1004.     
  1005.     /*Make the text box below*/
  1006.     textBox = NewTextBox(left, left + COLORWHEELWIDTH,
  1007.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  1008.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  1009.             PLAIN, "Text Color Label", "Color");
  1010.     SetVar(textBox, PARENT, panel);
  1011.     PrefixList(contents, textBox);
  1012.     SetTextAlign(textBox, CENTERALIGN);
  1013.  
  1014.     /*Make the brightness slider*/
  1015.     slider = NewSlider(right - SLIDERWIDTH, right, 
  1016.                top - COLORWHEELWIDTH, top,
  1017.                PLAIN, "Text Color Value");
  1018.     SetVar(slider, PARENT, panel);
  1019.     PrefixList(contents, slider);
  1020.     SetSliderRange(slider, 1.0, 0.0, 0.0);
  1021.     AssocBrightnessControlWithVar(slider, display, COLOR);
  1022.     SetVar(slider, HELPSTRING, NewString("This slider controls the \
  1023. value, or brightness, of the color used to draw the text in the clock display.  \
  1024. The final color is a combination of this value and the hue and saturation \
  1025. given by the Color color wheel."));
  1026.  
  1027.     /*Make the text box below*/
  1028.     textBox = NewTextBox(right - SLIDERWIDTH - MAJORBORDER, right + MAJORBORDER,
  1029.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  1030.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  1031.             PLAIN, "Text Value Label", "Value");
  1032.     SetVar(textBox, PARENT, panel);
  1033.     PrefixList(contents, textBox);
  1034.     SetTextAlign(textBox, CENTERALIGN);
  1035.  
  1036.     left -= MINORBORDER;    
  1037.     right += MINORBORDER;
  1038.     
  1039.     /*Make the background controls*/
  1040.     top = CDWINHEIGHT - MINORBORDER;
  1041.     right = CDWINWIDTH - MINORBORDER;
  1042.     left = right - (2 * MINORBORDER + 2 * MAJORBORDER + COLORWHEELWIDTH + SLIDERWIDTH);
  1043.     
  1044.     titleBox = NewTitleBox(left, right,
  1045.             top - TITLEBOXTOP - MINORBORDER - 2 * MINORBORDER - COLORWHEELWIDTH
  1046.                 - CHECKBOXHEIGHT - TEXTBOXHEIGHT - TEXTBOXSEP,
  1047.             top, "Background");
  1048.     SetVar(titleBox, PARENT, panel);
  1049.     PrefixList(contents, titleBox);
  1050.     left += MINORBORDER;
  1051.     right -= MINORBORDER;
  1052.     top -= TITLEBOXTOP + MINORBORDER;
  1053.  
  1054.     /*Make the color wheel*/
  1055.     colorWheel = NewColorWheel(left, left + COLORWHEELWIDTH,
  1056.             top - COLORWHEELWIDTH, top, "Background Color");
  1057.     SetVar(colorWheel, PARENT, panel);
  1058.     PrefixList(contents, colorWheel);
  1059.     AssocColorControlWithVar(colorWheel, display, BACKGROUND);
  1060.     SetVar(colorWheel, HELPSTRING, NewString("This color wheel controls the \
  1061. hue and saturation of the color used to draw the background of the clock display.  \
  1062. The final color is a combination of this hue and saturation and the value, or brightness, \
  1063. given by the Value slider."));
  1064.     
  1065.     /*Make the text box below*/
  1066.     textBox = NewTextBox(left, left + COLORWHEELWIDTH,
  1067.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  1068.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  1069.             PLAIN, "Background Color Label", "Color");
  1070.     SetVar(textBox, PARENT, panel);
  1071.     PrefixList(contents, textBox);
  1072.     SetTextAlign(textBox, CENTERALIGN);
  1073.  
  1074.     /*Make the brightness slider*/
  1075.     slider = NewSlider(right - SLIDERWIDTH, right, 
  1076.                top - COLORWHEELWIDTH, top,
  1077.                PLAIN, "Background Value");
  1078.     SetVar(slider, PARENT, panel);
  1079.     PrefixList(contents, slider);
  1080.     SetSliderRange(slider, 1.0, 0.0, 0.0);
  1081.     AssocBrightnessControlWithVar(slider, display, BACKGROUND);
  1082.     SetVar(slider, HELPSTRING, NewString("This slider controls the \
  1083. value, or brightness, of the color used to draw the background of the clock display.  \
  1084. The final color is a combination of this value and the hue and saturation \
  1085. given by the Color color wheel."));
  1086.  
  1087.     /*Make the text box below*/
  1088.     textBox = NewTextBox(right - SLIDERWIDTH - MAJORBORDER, right + MAJORBORDER,
  1089.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  1090.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  1091.             PLAIN, "Background Value Label", "Value");
  1092.     SetVar(textBox, PARENT, panel);
  1093.     PrefixList(contents, textBox);
  1094.     SetTextAlign(textBox, CENTERALIGN);
  1095.  
  1096.     /*Cross link the slider and color wheel*/
  1097.     SetVar(colorWheel, SLIDER, slider);
  1098.     SetVar(slider, COLORWHEEL, colorWheel);
  1099.  
  1100.     /*Make the check box*/
  1101.     top -= COLORWHEELWIDTH + TEXTBOXSEP + TEXTBOXHEIGHT + MINORBORDER;
  1102.     checkBox = NewCheckBox(left, right, 
  1103.         top - CHECKBOXHEIGHT, top,
  1104.         "No Background", true);
  1105.     SetVar(checkBox, PARENT, panel);
  1106.     PrefixList(contents, checkBox);
  1107.     AssocInhibitControlWithVar(checkBox, display, BACKGROUND, NewInt(UIBLACK));
  1108.     SetVar(checkBox, HELPSTRING, NewString("This checkbox controls whether \
  1109. a background is shown.  If it is selected, no background is shown, and the \
  1110. objects behind can be seen."));
  1111.  
  1112.     top -= CHECKBOXHEIGHT + MINORBORDER + MAJORBORDER;
  1113.     left = MINORBORDER;
  1114.     right = CDWINWIDTH - MINORBORDER;
  1115.  
  1116.     /*Create the format text box*/
  1117.     textBox = NewTextBox(left, left + CDFORMATLABELWIDTH, 
  1118.                 top - EDITBOXHEIGHT + (EDITBOXHEIGHT - TEXTBOXHEIGHT) / 2,
  1119.                 top - (EDITBOXHEIGHT - TEXTBOXHEIGHT) / 2, 
  1120.                 PLAIN, "Format:", "Format:");
  1121.     PrefixList(contents, textBox);
  1122.     SetVar(textBox, PARENT, panel);
  1123.         
  1124.     /*Create the format editable text box*/
  1125.     left = left + CDFORMATLABELWIDTH;
  1126.     format = GetVar(display, FORMAT);
  1127.     if (!format) SetVar(display, FORMAT, NewString("%#.2t"));
  1128.     textBox = NewTextBox(left, right, 
  1129.                 top - EDITBOXHEIGHT,
  1130.                 top, 
  1131.                 EDITABLE + WITH_PIT + ONE_LINE, "Format",
  1132.                 format ? GetString(format) : "%#.2t");
  1133.     PrefixList(contents, textBox);
  1134.     SetVar(textBox, PARENT, panel);
  1135.     SetVar(textBox, REPOBJ, display);
  1136.     SetVar(textBox, HELPSTRING, NewString(
  1137.         "This text box contains the format used to print the current time in \
  1138. the time readout.  It works very much like printf with the special conversion \
  1139. characters listed below.  Flags and field widths are exactly as in printf.  \
  1140. All times are printed as real numbers, so you may need to limit the number \
  1141. of decimal places.  \
  1142. There may be several conversions in one string, in which case, all will refer \
  1143. to the same time.  Hours and minutes are derives from the internal time specified in seconds.\n\
  1144. \n\
  1145. %h\t\tPrint the number of hours, from 1 to 12.\n\
  1146. %H\t\tPrint the number of hours, unrestricted.\n\
  1147. %i\t\tPrint the number of hours from 0 to 23.\n\
  1148. %m\t\tPrint the number of minutes, from 0 to 59.\n\
  1149. %M\t\tPrint the total number of minutes.\n\
  1150. %s\t\tPrint the number of seconds from 0 to 59.\n\
  1151. %S\t\tPrint the time in seconds.\n\
  1152. %t\t\tPrint the time in timesteps.  For this to work properly, \
  1153. each time step of data must have a time equal to the number of the time step.\n\
  1154. \n\
  1155. Examples for time = 43440 seconds:\n\
  1156. Format\t\t\t\tResult\t\tExplanation\n\
  1157. %.0t\t\t\t\t43440\t\tThe time is printed in seconds with no decimal places.\n\
  1158. %2.0h:%02.0m %a\t\t\t\t12:04 pm\t\tThe time is assumed to be 43440 seconds after \
  1159. midnight and is converted into 12-hour format.\n\
  1160. %.2M\t\t\t\t724.00\t\tThe time is printed in minutes with 2 decimal places."));
  1161.     AssocDirectControlWithVar(textBox, display, FORMAT);
  1162.  
  1163.     }
  1164.     return (ObjPtr) controlWindow;
  1165. }
  1166.  
  1167. #ifdef PROTO
  1168. ObjPtr NewTimeReadout(int left, int right, int bottom, int top, char *name, ObjPtr space)
  1169. #else
  1170. ObjPtr NewTimeReadout(left, right, bottom, top, name, space)
  1171. int left, right, bottom, top;
  1172. char *name;
  1173. ObjPtr space;
  1174. #endif
  1175. {
  1176.     ObjPtr clockThere;
  1177.     clockThere = NewTextBox(left, right, bottom, top, ADJUSTABLE, name, "");
  1178.     SetMethod(clockThere, DELETEICON, DeleteClockReadout);
  1179.     DeclareDependency(clockThere, VALUE, FORMAT);
  1180.     SetVar(clockThere, SPACE, space);
  1181.     DeclareIndirectDependency(clockThere, VALUE, SPACE, TIME);
  1182.     SetMethod(clockThere, NEWCTLWINDOW, ShowClockDisplayControls);
  1183.     SetMethod(clockThere, VALUE, MakeClockValue);
  1184.     SetVar(clockThere, FORMAT, NewString("%#.2t"));
  1185.     SetVar(clockThere, HELPSTRING, NewString("This time readout displays the time \
  1186. given by the clock in this space.  The display format is controlled by the Format \
  1187. text box in the readout's control panel.\n"));
  1188.     return clockThere;
  1189. }
  1190.  
  1191. #ifdef INTERACTIVE
  1192. static ObjPtr PressSpacePanel(object, x, y, flags)
  1193. ObjPtr object;
  1194. int x, y;
  1195. long flags;
  1196. /*Does a press in a field beginning at x and y.  Returns
  1197.   true iff the press really was in the field.*/
  1198. {
  1199.     int left, right, bottom, top;
  1200.     FuncTyp pressContents;        /*Routine to press the contents*/
  1201.  
  1202.     Get2DIntBounds(object, &left, &right, &bottom, &top);
  1203.  
  1204.     if (x >= left && x <= right && y >= bottom && y <= top)
  1205.     {
  1206.     /*Hey!  It really was a click in the field*/
  1207.     ObjPtr space;
  1208.     int tool;
  1209.     ObjPtr contents;
  1210.     ObjPtr retVal = ObjFalse;
  1211.  
  1212.         contents = GetVar(object, CONTENTS);
  1213.  
  1214.     if (TOOL(flags) == T_HELP)
  1215.     {
  1216.         StartPanel(left, right, bottom, top);
  1217.         x -= left;
  1218.         y -= bottom;
  1219.         retVal = PressObject(contents, x, y, flags);
  1220.         StopPanel();
  1221.         return retVal;
  1222.     }
  1223.  
  1224.     if (flags & F_OPTIONDOWN)
  1225.     {
  1226.         /*Ignore press if this is the front panel*/
  1227.         if (GetPredicate(object, FRONTPANEL))
  1228.         {
  1229.         return ObjFalse;
  1230.         }
  1231.     }
  1232.  
  1233.     if (TOOL(flags) == T_ROTATE) flags |= F_SHIFTDOWN;
  1234.  
  1235.     SetScreenGrid(object);
  1236.  
  1237.     /*See if it's a dragBuffer click*/
  1238.     if (dragBuffer)
  1239.     {
  1240.         /*Yes it is.  Move dragBuffer and exit*/
  1241.         dropObject = dragBuffer;
  1242.         dragBuffer = NULLOBJ;
  1243.         return ObjTrue;
  1244.     }
  1245.  
  1246.         /*Setup the new viewport*/
  1247.     StartPanel(left, right, bottom, top);
  1248.  
  1249.         x -= left;
  1250.         y -= bottom;
  1251.     
  1252.     tool = ST_FINGER;
  1253.     space = GetVar(object, SPACE);
  1254.     if (space)
  1255.     {
  1256.         ObjPtr var;
  1257.         var = GetVar(space, EDITTOOL);
  1258.         if (var)
  1259.         {
  1260.         tool = GetInt(var); 
  1261.         }
  1262.     }
  1263.     if (TOOL(flags) == T_HELP)
  1264.     {
  1265.         tool = ST_FINGER;
  1266.     }
  1267.  
  1268.     switch (tool)
  1269.     {
  1270.         case ST_EYEDROPPER:
  1271.         /*Get color under cursor*/
  1272.         {
  1273.             Pixel pixel;
  1274.             ObjPtr var;
  1275.             real *elements;
  1276.  
  1277.             x += left;
  1278.             y += bottom;
  1279.             lrectread((Screencoord) x, (Screencoord) y, 
  1280.             (Screencoord) x, (Screencoord) y, (unsigned long *) &pixel);
  1281.             printf("%d %d %d\n", pixel . red, pixel . green, pixel . blue);
  1282.  
  1283.             var = NewRealArray(1, 3L);
  1284.             elements = ELEMENTS(var);
  1285.  
  1286.             elements[0] = ((real) pixel . red) / 255.0;
  1287.             elements[1] = ((real) pixel . green) / 255.0;
  1288.             elements[2] = ((real) pixel . blue) / 255.0;
  1289.  
  1290.             ToClipboard(var);
  1291.             retVal = ObjTrue;
  1292.         }
  1293.         break;
  1294.         case ST_FINGER:
  1295.         retVal = PressObject(contents, x, y, flags);
  1296.  
  1297.         if (TOOL(flags) == T_HELP && !IsTrue(retVal))
  1298.         {
  1299.             ContextHelp(object);
  1300.             StopPanel();
  1301.             return ObjTrue;
  1302.         }
  1303.         else if (!IsTrue(retVal))
  1304.         {
  1305.             {
  1306.             StopPanel();
  1307.             if (!GetPredicate(object, FRONTPANEL))
  1308.             {
  1309.                 ObjPtr space;
  1310.                 if (0 == (flags & F_SHIFTDOWN))
  1311.                 {
  1312.                 DeselectAll();
  1313.                 }
  1314.  
  1315.                 /*Return press to space*/
  1316.                 space = GetVar(object, SPACE);
  1317.                 if (TOOL(flags) == T_ROTATE)
  1318.                 {
  1319.                 RotateSpace(space, x + left, y + bottom, flags);
  1320.                 }
  1321.                 else
  1322.                 {
  1323.                 MoveSpace(space, x + left, y + bottom, flags);
  1324.                 }
  1325.                 return ObjTrue;
  1326.             }
  1327.             else
  1328.             {
  1329.                 return ObjFalse;
  1330.             }
  1331.             }
  1332.         }
  1333.         retVal = ObjTrue;
  1334.         break;
  1335.         case ST_ANNOTATION:
  1336.         case ST_RECTANGLE:
  1337.         case ST_LINE:
  1338.         case ST_TIME_READOUT:
  1339.         {
  1340.             char name[30];
  1341.             int l, r, b, t;
  1342.             int minSize;
  1343.             ObjPtr boundsArray;
  1344.             ObjPtr screenObject;
  1345.             int startX, startY, newX, newY, endX, endY;
  1346.  
  1347.             if (flags & F_SHIFTDOWN)
  1348.             {
  1349.             x = GRIDX(x);
  1350.             y = GRIDY(y);
  1351.             }
  1352.  
  1353.             startX = x;
  1354.             startY = y;
  1355.  
  1356.             if (tool == ST_ANNOTATION || tool == ST_TIME_READOUT)
  1357.             {
  1358.             minSize = MINANNOTSIZE;
  1359.             }
  1360.             else if (tool == ST_RECTANGLE)
  1361.             {
  1362.             minSize = MINRECTSIZE;
  1363.             }
  1364.             else if (tool == ST_LINE)
  1365.             {
  1366.             minSize = MINLINESIZE;
  1367.             }
  1368.  
  1369.             l = startX - HANDLESIZE / 2;
  1370.             r = startX + minSize + HANDLESIZE / 2;
  1371.             b = startY - minSize - HANDLESIZE / 2;
  1372.             t = startY + HANDLESIZE / 2;
  1373.  
  1374.             if (tool == ST_ANNOTATION)
  1375.             {
  1376.             sprintf(name, "Annotation %d", nAnnot++);
  1377.  
  1378.                 screenObject = NewTextBox(l, r, b, t,
  1379.                     /*WITH_BG + */EDITABLE + ADJUSTABLE, name, "");
  1380.             SetMethod(screenObject, CLONE, CloneAnnotation);
  1381.             SetMethod(screenObject, DUPLICATE, DuplicateDrawing);
  1382.             SetMethod(screenObject, PUSHTOBOTTOM, PushDrawingToBottom);
  1383.             SetMethod(screenObject, BRINGTOTOP, BringDrawingToTop);
  1384.             SetMethod(screenObject, MOVETOBACKPANEL, MoveDrawingToBackPanel);
  1385.             SetMethod(screenObject, MOVETOFRONTPANEL, MoveDrawingToFrontPanel);
  1386.             }
  1387.             else if (tool == ST_TIME_READOUT)
  1388.             {
  1389.             sprintf(name, "Time Readout %d", nTimeReadout++);
  1390.  
  1391.                 screenObject = NewTimeReadout(l, r, b, t, name, space);
  1392.             SetMethod(screenObject, CLONE, CloneTimeReadout);
  1393.             SetMethod(screenObject, DUPLICATE, DuplicateDrawing);
  1394.             SetMethod(screenObject, PUSHTOBOTTOM, PushDrawingToBottom);
  1395.             SetMethod(screenObject, BRINGTOTOP, BringDrawingToTop);
  1396.             SetMethod(screenObject, MOVETOBACKPANEL, MoveDrawingToBackPanel);
  1397.             SetMethod(screenObject, MOVETOFRONTPANEL, MoveDrawingToFrontPanel);
  1398.             }
  1399.             else if (tool == ST_RECTANGLE)
  1400.             {
  1401.             sprintf(name, "Rectangle %d", nRect++);
  1402.  
  1403.             screenObject = NewRectangle(l, r, b, t, name);
  1404.             }
  1405.             else if (tool == ST_LINE)
  1406.             {
  1407.             sprintf(name, "Line %d", nLine++);
  1408.  
  1409.             screenObject = NewLine(startX, startY, startX, startY, name);
  1410.             }
  1411.             SetVar(screenObject, STICKINESS, NewInt(FLOATINGLEFT + FLOATINGRIGHT + FLOATINGTOP + FLOATINGBOTTOM));
  1412.             PrefixList(contents, screenObject);
  1413.             SetVar(screenObject, PARENT, object);
  1414.             if (tool == ST_ANNOTATION)
  1415.             {
  1416.             SetTextColor(screenObject, NewInt(UIWHITE));
  1417.             ImInvalid(screenObject);
  1418.             SetTextFont(screenObject, ANNOTFONT);
  1419.             SetTextSize(screenObject, ANNOTFONTSIZE);
  1420.             SetMethod(screenObject, DELETEICON, DeleteSpacePanelText);
  1421.             SetMethod(screenObject, DELETE, DeleteObject);
  1422.             }
  1423.             else if (tool == ST_TIME_READOUT)
  1424.             {
  1425.             SetTextColor(screenObject, NewInt(UIWHITE));
  1426.             ImInvalid(screenObject);
  1427.             SetTextFont(screenObject, ANNOTFONT);
  1428.             SetTextSize(screenObject, ANNOTFONTSIZE);
  1429.             SetMethod(screenObject, DELETEICON, DeleteClockReadout);
  1430.             SetMethod(screenObject, DELETE, DeleteObject);
  1431.             }
  1432.  
  1433.             if (tool == ST_ANNOTATION || tool == ST_TIME_READOUT)
  1434.             {
  1435.             InhibitLogging(true);
  1436.             Select(screenObject, true);
  1437.             InhibitLogging(false);
  1438.             }
  1439.  
  1440.             /*Set up to draw in the overlay area*/
  1441.             DrawSkeleton(true);
  1442.  
  1443.             DrawMe(screenObject);
  1444.  
  1445.             while (Mouse(&newX, &newY))
  1446.             {
  1447.  
  1448.             if (tool == ST_ANNOTATION ||
  1449.                 tool == ST_TIME_READOUT ||
  1450.                 tool == ST_RECTANGLE ||
  1451.                 tool == ST_LINE)
  1452.             {
  1453.                 if (newX >= startX && newX - startX < minSize)
  1454.                 {
  1455.                 newX = startX + minSize;
  1456.                 }
  1457.                 else if (newX < startX && startX - newX < minSize)
  1458.                 {
  1459.                 newX = startX - minSize;
  1460.                 }
  1461.  
  1462.                 if (newY >= startY && newY - startY < minSize)
  1463.                 {
  1464.                 newY = startY + minSize;
  1465.                 }
  1466.                 else if (newY < startY && startY - newY < minSize)
  1467.                 {
  1468.                 newY = startY - minSize;
  1469.                 }
  1470.             }
  1471.  
  1472.             if (flags & F_SHIFTDOWN)
  1473.             {
  1474.                 newX = GRIDX(newX);
  1475.                 newY = GRIDY(newY);
  1476.             }
  1477.             if (newX != x || newY != y)
  1478.             {
  1479.                 x = newX;
  1480.                 y = newY;
  1481.                 Set2DIntBounds(screenObject,
  1482.                     MIN(startX, x) - HANDLESIZE / 2,
  1483.                     MAX(startX, x) + HANDLESIZE / 2,
  1484.                     MIN(startY, y) - HANDLESIZE / 2, 
  1485.                     MAX(startY, y) + HANDLESIZE / 2);
  1486.                 if (tool == ST_LINE)
  1487.                 {
  1488.                 ObjPtr var;
  1489.                 real loc[2];
  1490.                 loc[0] = newX;
  1491.                 loc[1] = newY;
  1492.                 var = NewRealArray(1, 2L);
  1493.                 CArray2Array(var, loc);
  1494.                 SetVar(screenObject, ENDPOINT, var);
  1495.                 }
  1496.                 DrawMe(screenObject);
  1497.             }
  1498.             }
  1499.             DrawSkeleton(false);
  1500.             Get2DIntBounds(screenObject, &l, &r, &b, &t);
  1501.  
  1502.             if (logging)
  1503.             {
  1504.             /*Log the action.*/
  1505.             char cmd[256];
  1506.             char *d, *s;
  1507.  
  1508.             s = name;
  1509.             d = &(cmd[0]);
  1510.             if (tool == ST_ANNOTATION)
  1511.             {
  1512.                 strcpy(cmd, "annotation ");
  1513.             }
  1514.             else if (tool == ST_RECTANGLE)
  1515.             {
  1516.                 strcpy(cmd, "rectangle ");
  1517.             }
  1518.             else if (tool == ST_LINE)
  1519.             {
  1520.                 strcpy(cmd, "line ");
  1521.             }
  1522.             else if (tool == ST_TIME_READOUT)
  1523.             {
  1524.                 strcpy(cmd, "timereadout ");
  1525.             }
  1526.             while (*d) ++d;
  1527.             MakeObjectName(d, screenObject);
  1528.             while (*d) ++d;
  1529.             if (tool == ST_LINE)
  1530.             {
  1531.                 sprintf(d, " %d %d %d %d\n",
  1532.                 startX, startY, x, y);
  1533.             }
  1534.             else
  1535.             {
  1536.                 sprintf(d, " [%d %d %d %d]\n",
  1537.                 l, r, b, t);
  1538.             }
  1539.             Log(cmd);
  1540.  
  1541.             if (flags & F_OPTIONDOWN)
  1542.             {
  1543.                 strcpy(d, "move ");
  1544.                 d = &(cmd[0]);
  1545.                 while (*d) ++d;
  1546.                 MakeObjectName(d, screenObject);
  1547.                 while (*d) ++d;
  1548.                 strcpy(d, " to back panel\n");
  1549.                 Log(cmd);
  1550.             }
  1551.             }
  1552.             SetValue(GetVar(space, TOOLGROUP), NewInt(ST_FINGER));
  1553.  
  1554.             if (!(flags & F_SHIFTDOWN))
  1555.             {
  1556.             DeselectAll();
  1557.             IdleAllWindows();
  1558.             }
  1559.  
  1560.             Select(screenObject, true);
  1561.             if (tool == ST_ANNOTATION)
  1562.             {
  1563.             MakeMeCurrent(screenObject);
  1564.             }
  1565.         }
  1566.         retVal = ObjTrue;
  1567.         break;
  1568.     }
  1569.  
  1570.     StopPanel();
  1571.     return retVal;
  1572.     }
  1573.     else
  1574.     {
  1575.     return ObjFalse;
  1576.     }
  1577. }
  1578. #endif
  1579.  
  1580. void SetupVisualizeAsList()
  1581. {
  1582.     EmptyList(visualizeAsList);
  1583. }
  1584.  
  1585. void AddToVisualizeAsList(object)
  1586. ObjPtr object;
  1587. {
  1588.     PostfixList(visualizeAsList, object);
  1589. }
  1590.  
  1591. void EmptyVisualizeAsList()
  1592. {
  1593.     EmptyList(visualizeAsList);
  1594. }
  1595.  
  1596. ObjPtr ChangeCorralButton(object)
  1597. ObjPtr object;
  1598. /*Changedvalue for a corral button*/
  1599. {
  1600.     ObjPtr corral, parent, value, curButton;
  1601.  
  1602.     value = GetValue(object);
  1603.  
  1604.     parent = GetObjectVar("ChangeCorralButton", object, PARENT);
  1605.     if (!parent) return ObjFalse;
  1606.     corral = GetObjectVar("ChangeCorralButton", object, CORRAL);
  1607.     if (!corral) return ObjFalse;
  1608.     curButton = GetVar(parent, BUTTON);
  1609.  
  1610.     if (value && IsInt(value) && 0 == GetInt(value) && curButton != object)
  1611.     {
  1612.     SetVar(corral, CONTENTS, GetVar(object, PANELCONTENTS));
  1613.     if (curButton)
  1614.     {
  1615.         SetVar(curButton, VALUE, NewInt(0));
  1616.     }
  1617.     SetVar(object, VALUE, NewInt(1));
  1618.     SetVar(parent, BUTTON, object);
  1619.     ImInvalid(corral);
  1620.     return ObjTrue;
  1621.     }
  1622.     else
  1623.     {
  1624.     return ObjTrue;
  1625.     }
  1626. }
  1627.  
  1628. void NewVisAsWindow()
  1629. /*Brings up a new, empty visAs window*/
  1630. {
  1631.     WinInfoPtr newWindow;
  1632.     ObjPtr objList, contents, fieldContents;
  1633.     ObjPtr corral, panel, button, icon;
  1634.     ObjPtr textBox;
  1635.     ObjPtr controlField;
  1636.     ThingListPtr runner;
  1637.     int whichIcon;
  1638.     int bw;
  1639.     char *name;
  1640.     ObjPtr var;
  1641.     int x;
  1642.     int l, r, b, t;
  1643.  
  1644.     /*Create a vis as window*/
  1645.     sprintf(tempStr, "Visualize As %d", ++vawSerialNumber); 
  1646.     newWindow = NewObjWindow(NULLOBJ, tempStr, WINUI,
  1647.         VAWINWIDTH, VAWINHEIGHT, SCRWIDTH, SCRHEIGHT);
  1648.  
  1649.     SetVar((ObjPtr) newWindow, HELPSTRING,
  1650.         NewString("This window shows all the possible ways to visualize a \
  1651. group of datasets."));
  1652.  
  1653.     /*Put in a panel*/
  1654.     panel = NewPanel(greyPanelClass, 0, VAWINWIDTH, 0, VAWINHEIGHT);
  1655.     SetVar(panel, STICKINESS, NewInt(STICKYLEFT + STICKYRIGHT +
  1656.                      STICKYBOTTOM + STICKYTOP));
  1657.  
  1658.     contents = GetVar((ObjPtr) newWindow, CONTENTS);
  1659.     PrefixList(contents, panel);
  1660.     SetVar(panel, PARENT, (ObjPtr) newWindow);
  1661.  
  1662.     /*Put in contents*/
  1663.     contents = GetListVar("NewVisAsWindow", panel, CONTENTS);
  1664.     if (!contents)
  1665.     {
  1666.     return;
  1667.     }
  1668.  
  1669.     /*Explanatory text at top*/
  1670.     textBox = TemplateTextBox(VisAsTemplate, "Visualize As String", 0, "Visualize datasets as...");
  1671.     PrefixList(contents, textBox);
  1672.     SetVar((ObjPtr) newWindow, TITLETEXT, textBox);
  1673.     SetVar(textBox, PARENT, panel);
  1674.  
  1675.     /*Icon corral*/
  1676.     corral = TemplateIconCorral(VisAsTemplate, "Visualizations Corral", NULLOBJ,
  1677.         OBJECTSFROMTOP + BARRIGHT + BARBOTTOM);
  1678.     SetVar(corral, STICKINESS, NewInt(STICKYLEFT + STICKYRIGHT +
  1679.                      STICKYBOTTOM + STICKYTOP));
  1680.     SetVar((ObjPtr) newWindow, CORRAL, corral);
  1681.     SetVar(corral, HELPSTRING,
  1682.     NewString("This corral contains icons for all possible visualizations of a group of \
  1683. datasets.  You can visualize or show info on the visualizations by selecting \
  1684. some of them and pressing the buttons at the bottom of the window.  You can delete \
  1685. visualizations by selecting them and choosing Delete from the Object menu."));
  1686.     PrefixList(contents, corral);
  1687.     SetVar(corral, PARENT, panel);
  1688.     SetVar((ObjPtr) newWindow, CORRAL, corral);
  1689.  
  1690.     /*Control field*/
  1691.     controlField = TemplateControlField(VisAsTemplate, "Visualization Type Field",
  1692.         BARBOTTOM);
  1693.     SetVar(controlField, STICKINESS, NewInt(STICKYLEFT + STICKYRIGHT + STICKYTOP));
  1694.     SetVar(controlField, PARENT, panel);
  1695.     PrefixList(contents, controlField);
  1696.     SetVar((ObjPtr) newWindow, VISASFIELD, controlField);
  1697.  
  1698.     /*Buttons in the control field*/
  1699.     fieldContents = GetVar(controlField, CONTENTS);
  1700.     runner = LISTOF(allVisObjClasses);
  1701.     x = 0;
  1702.     while (runner)
  1703.     {
  1704.     icon = GetVar(runner -> thing, DEFAULTICON);
  1705.     var = GetIntVar("ShowVisControls", icon, WHICHICON);
  1706.     if (var)
  1707.     {
  1708.         whichIcon = GetInt(var);
  1709.     }
  1710.     else
  1711.     {
  1712.         whichIcon = ICONQUESTION;
  1713.     }
  1714.     var = GetVar(runner -> thing, NAME);
  1715.     if (var)
  1716.     {
  1717.         name = GetString(var);
  1718.     }
  1719.     else
  1720.     {
  1721.         name = "?";
  1722.     }
  1723.  
  1724.     /*Make a button*/
  1725.     button = NewIconLabeledButton(x, x + VAWINICONBUTWIDTH, 0, CWINICONBUTHEIGHT,
  1726.             whichIcon, UIYELLOW, name, BS_PITTED);
  1727.     x += VAWINICONBUTWIDTH;
  1728.     SetMethod(button, ICONEXTRADRAW, GetMethod(icon, ICONEXTRADRAW));
  1729.  
  1730.     SetMethod(button, CHANGEDVALUE, ChangeCorralButton);
  1731.  
  1732.     SetVar(button, CORRAL, corral);
  1733.     PostfixList(fieldContents, button);
  1734.     SetVar(button, PARENT, controlField);
  1735.  
  1736.     runner = runner -> next;
  1737.     }
  1738.     RecalcScroll(controlField);
  1739.  
  1740.  
  1741.     l = b = 0;
  1742.     r = VAWINWIDTH;
  1743.     t = VAWINHEIGHT;
  1744.  
  1745.     l += MINORBORDER;
  1746.     r -= MINORBORDER;
  1747.     b += MINORBORDER;
  1748.     t = b + BUTTONHEIGHT;
  1749.     bw = (r - l - MINORBORDER) / 2;
  1750.  
  1751.     /*Make a visualize button*/
  1752.     button = NewFunctionButton(newWindow,
  1753.         l, l + bw,
  1754.         b, b + BUTTONHEIGHT, OF_VISUALIZE); 
  1755.     if (button)
  1756.     {
  1757.     SetVar(button, PARENT, panel);
  1758.     SetVar(button, STICKINESS, NewInt(STICKYBOTTOM + STICKYLEFT + FLOATINGRIGHT));
  1759.     PrefixList(contents, button);
  1760.     }
  1761.  
  1762.     /*Make a show info button*/
  1763.     button = NewFunctionButton(newWindow,
  1764.         r - bw, 
  1765.         r,
  1766.         b, b + BUTTONHEIGHT, OF_SHOW_CONTROLS); 
  1767.     if (button)
  1768.     {
  1769.     SetVar(button, PARENT, panel);
  1770.     SetVar(button, STICKINESS, NewInt(STICKYBOTTOM + FLOATINGLEFT + STICKYRIGHT));
  1771.     PrefixList(contents, button);
  1772.     }
  1773.  
  1774.     /*Set up the list for modifications*/
  1775.     SetupVisualizeAsList();
  1776. }
  1777.  
  1778.  
  1779. void ProcessVisAsList()
  1780. /*Processes the visualize as modification list*/
  1781. {
  1782.     ObjPtr allFilters;
  1783.     ThingListPtr visRunner, dataRunner, buttonRunner;
  1784.     ObjPtr firstSuccessful;
  1785.     ObjPtr contentsList, visList, var;
  1786.     ObjPtr corral;
  1787.  
  1788.     if (!selWinInfo)
  1789.     {
  1790.     return;
  1791.     }
  1792.  
  1793.     if (!visualizeAsList)
  1794.     {
  1795.     return;
  1796.     }
  1797.  
  1798.     if (LISTOF(visualizeAsList))
  1799.     {
  1800.     /*There's at least one vis as*/
  1801.     ObjPtr var, textBox;
  1802.  
  1803.     if (LISTOF(visualizeAsList) -> next)
  1804.     {
  1805.         /*More than one, don't bother changing text */
  1806.     }
  1807.     else
  1808.     {
  1809.  
  1810.         var = GetVar(LISTOF(visualizeAsList) -> thing, NAME);
  1811.         textBox = GetVar((ObjPtr) selWinInfo, TITLETEXT);
  1812.         if (var && textBox)
  1813.         {
  1814.         sprintf(tempStr, "Visualize %s as...", GetString(var));
  1815.         SetValue(textBox, NewString(tempStr));
  1816.         }
  1817.     }
  1818.     }
  1819.  
  1820.     /*Find all modifications for the list of filters*/
  1821.     allFilters = AllEasyFilters(visualizeAsList);
  1822.  
  1823.     corral = GetObjectVar("ProcessVisAsList", (ObjPtr) selWinInfo, CORRAL);
  1824.     if (!corral) return;
  1825.  
  1826.     var = GetObjectVar("ProcessVisAsList", (ObjPtr) selWinInfo, VISASFIELD);
  1827.     if (!var) return;
  1828.     var = GetListVar("ProcessVisAsList", var, CONTENTS);
  1829.     if (!var) return;
  1830.     buttonRunner = LISTOF(var);
  1831.  
  1832.     /*Go through all the visualization objects*/ 
  1833.     firstSuccessful = NULLOBJ;
  1834.     visRunner = LISTOF(allVisObjClasses);
  1835.     while (visRunner)
  1836.     {
  1837.     contentsList = NewList();
  1838.  
  1839.     /*Do visualization just on normal data*/
  1840.     dataRunner = LISTOF(visualizeAsList);
  1841.     while (dataRunner)
  1842.     {
  1843.         visList = GetAllVis(dataRunner -> thing, false, visRunner -> thing);
  1844.         if (visList)
  1845.         {
  1846.         ThingListPtr runner;
  1847.         runner = LISTOF(visList);
  1848.         while (runner)
  1849.         {
  1850.             ObjPtr vis, icon;
  1851.             vis = runner -> thing;
  1852.             if (vis)
  1853.             {
  1854.             SetVar(vis, TEMPLATEP, ObjTrue);
  1855.             icon = NewVisIcon(vis);
  1856.             if (icon)
  1857.             {
  1858.                 ObjPtr format;
  1859.                 format = GetVar(icon, FORMAT);
  1860.                 if (format)
  1861.                 {
  1862.                 SetVar(icon, FORMAT, format);
  1863.                 }
  1864.                 SetVar(icon, CORRAL, corral);
  1865.                 SetVar(icon, ICONLOC, NULLOBJ);
  1866.                 PostfixList(contentsList, icon);
  1867.                 if (!firstSuccessful)
  1868.                 {
  1869.                 firstSuccessful = buttonRunner -> thing;
  1870.                 }
  1871.             }
  1872.             }
  1873.             runner = runner -> next;
  1874.         }
  1875.         }
  1876.         dataRunner = dataRunner -> next;
  1877.     }
  1878.  
  1879.     /*Do visualization on filtered data*/
  1880.     if (allFilters)
  1881.     {
  1882.     dataRunner = LISTOF(allFilters);
  1883.     while (dataRunner)
  1884.     {
  1885.         visList = GetAllVis(dataRunner -> thing, false, visRunner -> thing);
  1886.         if (visList)
  1887.         {
  1888.         ThingListPtr runner;
  1889.         runner = LISTOF(visList);
  1890.         while (runner)
  1891.         {
  1892.             ObjPtr vis, icon;
  1893.             vis = runner -> thing;
  1894.             if (vis)
  1895.             {
  1896.             SetVar(vis, TEMPLATEP, ObjTrue);
  1897.             icon = NewVisIcon(vis);
  1898.             if (icon)
  1899.             {
  1900.                 ObjPtr format;
  1901.                 format = GetVar(icon, FORMAT);
  1902.                 if (format)
  1903.                 {
  1904.                 SetVar(icon, FORMAT, format);
  1905.                 }
  1906.                 SetVar(icon, CORRAL, corral);
  1907.                 SetVar(icon, ICONLOC, NULLOBJ);
  1908.                 PostfixList(contentsList, icon);
  1909.                 if (!firstSuccessful)
  1910.                 {
  1911.                 firstSuccessful = buttonRunner -> thing;
  1912.                 }
  1913.             }
  1914.             }
  1915.             runner = runner -> next;
  1916.         }
  1917.         }
  1918.         dataRunner = dataRunner -> next;
  1919.     }
  1920.     }
  1921.  
  1922.     SetVar(buttonRunner -> thing, PANELCONTENTS, contentsList);
  1923.     buttonRunner = buttonRunner -> next;
  1924.  
  1925.     visRunner = visRunner -> next;
  1926.     }
  1927.  
  1928.     if (firstSuccessful)
  1929.     {
  1930.     InhibitLogging(true);
  1931.     SetValue(firstSuccessful, ObjTrue);
  1932.     InhibitLogging(false);
  1933.     }
  1934.  
  1935.     EmptyVisualizeAsList();
  1936. }
  1937.  
  1938. void VisObjectsAs()
  1939. /*Opens a new VisObjectsAs window using default for all of the
  1940.   selected objects.
  1941. */
  1942. {
  1943.     DoObjFunction(OF_VISUALIZE_AS);
  1944. }
  1945.  
  1946. static ObjPtr DropInVisCorral(corral, object, x, y)
  1947. ObjPtr corral, object;
  1948. int x, y;
  1949. /*Drops an icon in a vis corral*/
  1950. {
  1951.     ObjPtr repObj;
  1952.     repObj = GetVar(object, REPOBJ);
  1953.     if (repObj)
  1954.     {
  1955.     real loc[2];
  1956.     ObjPtr locArray;
  1957.     loc[0] = x;
  1958.     loc[1] = y;
  1959.     locArray = NewRealArray(1, 2L);
  1960.     CArray2Array(locArray, loc);
  1961.     if (IsController(repObj))
  1962.     {
  1963.         AddControllerToSpace(repObj, FindSpace(selWinInfo), GetVar((ObjPtr) selWinInfo, CORRAL), locArray);
  1964.         ImInvalid(repObj);
  1965.     }
  1966.     else
  1967.     {
  1968.         AddObjToSpace(repObj, FindSpace(selWinInfo), GetVar((ObjPtr) selWinInfo, CORRAL), locArray, NULLOBJ);
  1969.         IdleAllWindows();
  1970.     }
  1971.     return ObjTrue;
  1972.     }
  1973.     else
  1974.     {
  1975.     return ObjFalse;
  1976.     }
  1977. }
  1978.  
  1979. void ForAllVisWindows(routine)
  1980. void (*routine)();
  1981. /*Performs (*routine)(window) on all visualization windows*/
  1982. {
  1983.     WinInfoPtr curWindow;
  1984.  
  1985.     curWindow = allWindows;
  1986.     while (curWindow)
  1987.     {
  1988.     if (IsVisWindow((ObjPtr) curWindow))
  1989.     {
  1990.         (*routine)(curWindow);
  1991.     }
  1992.     curWindow = curWindow -> next;
  1993.     }
  1994. }
  1995.  
  1996. void PushNonVisWindows()
  1997. /*Pushes all the non vis windows*/
  1998. {
  1999. #ifdef GRAPHICS
  2000. #ifdef WINDOWS4D
  2001.     int maxDepth;
  2002.     WinInfoPtr curWindow;
  2003.     maxDepth = -1;
  2004.  
  2005.     curWindow = allWindows;
  2006.     while (curWindow)
  2007.     {
  2008.     if (IsVisWindow((ObjPtr) curWindow))
  2009.     {
  2010.         if ((curWindow) -> id)
  2011.         {
  2012.         maxDepth = MAX(maxDepth, windepth((curWindow) -> id));
  2013.         }
  2014.     }
  2015.     curWindow = curWindow -> next;
  2016.     }
  2017.  
  2018.     curWindow = allWindows;
  2019.     while (curWindow)
  2020.     {
  2021.     if (!IsVisWindow((ObjPtr) curWindow))
  2022.     {
  2023.         if ((curWindow) -> id && windepth((curWindow) -> id) < maxDepth)
  2024.         {
  2025.         SelWindow(curWindow);
  2026.         settleEvents = 20;
  2027.         --maxDepth;
  2028.         winpush();
  2029.         }
  2030.     }
  2031.     curWindow = curWindow -> next;
  2032.     }
  2033. #endif
  2034. #endif
  2035. }
  2036.  
  2037. void Tile(width, height)
  2038. int width, height;
  2039. /*Tiles all the vis windows in the lower left corner as big as width, height*/
  2040. {
  2041. #ifdef GRAPHICS
  2042. #ifdef WINDOWS4D
  2043.     int nWide, nHigh;        /*# of windows wide and high*/
  2044.     int i, j;
  2045.     int nVisWindows;
  2046.     WinInfoPtr curWindow;
  2047.     long oldWindow;
  2048.  
  2049.     if (logging)
  2050.     {
  2051.     char cmd[256];
  2052.     sprintf(cmd, "tile %d %d\n", width, height);
  2053.     Log(cmd);
  2054.     }
  2055.  
  2056.     /*Count the number of vis windows*/
  2057.     nVisWindows = 0;
  2058.     curWindow = allWindows;
  2059.     while (curWindow)
  2060.     {
  2061.     if (IsVisWindow((ObjPtr) curWindow))
  2062.     {
  2063.         ++nVisWindows;
  2064.     }
  2065.     curWindow = curWindow -> next;
  2066.     }
  2067.     if (!nVisWindows) return;
  2068.  
  2069.     /*Estimate the number of windows high*/
  2070.     nHigh = sqrt((double) nVisWindows) + 0.49;
  2071.     nWide = nVisWindows / nHigh;
  2072.     if (nWide * nHigh < nVisWindows) ++nHigh;
  2073.  
  2074.     /*Go through and tile the windows*/
  2075.     i = 0;
  2076.     j = nHigh - 1;
  2077.     curWindow = allWindows;
  2078.     while (curWindow)
  2079.     {
  2080.     if (IsVisWindow((ObjPtr) curWindow))
  2081.     {
  2082.         long l, r, b, t;
  2083.         
  2084.         if (i)
  2085.         {
  2086.         l = i * width / nWide + 1;
  2087.         }
  2088.         else
  2089.         {
  2090.         l = 0;
  2091.         }
  2092.         r = (i + 1) * width / nWide;
  2093.         if (j)
  2094.         {
  2095.         b = j * height / nHigh + 1;
  2096.         }
  2097.         else
  2098.         {
  2099.         b = 0;
  2100.         }
  2101.         t = (j + 1) * height / nHigh;
  2102.         if (++i >= nWide)
  2103.         {
  2104.         i = 0;
  2105.         --j;
  2106.         }
  2107.  
  2108.         /*Move the window*/
  2109.         SelWindow(curWindow);
  2110.         SetWindowPosition(l, r, b, t);
  2111.     }
  2112.     curWindow = curWindow -> next;
  2113.     }
  2114. #endif
  2115. #endif
  2116. }
  2117.  
  2118. void DoTileFullScreen()
  2119. /*Tiles all the visualization windows within the full screen*/
  2120. {
  2121.     Tile(SCRWIDTH, SCRHEIGHT);
  2122. }
  2123.  
  2124. void DoTileVideoScreen()
  2125. /*Tiles all the visualization windows within the full screen*/
  2126. {
  2127.     int x, y;
  2128.     GetScreenSize(&x, &y);
  2129.  
  2130.     Tile(x, y);
  2131. }
  2132.  
  2133. static ObjPtr TileFullScreen(win)
  2134. ObjPtr win;
  2135. /*Tiles all the visualization windows within the full screen*/
  2136. {
  2137.     Tile(SCRWIDTH, SCRHEIGHT);
  2138.     return ObjTrue;
  2139. }
  2140.  
  2141. static ObjPtr TileVideoScreen(win)
  2142. ObjPtr win;
  2143. /*Tiles all the visualization windows within the full screen*/
  2144. {
  2145.     int x, y;
  2146.     GetScreenSize(&x, &y);
  2147.  
  2148.     Tile(x, y);
  2149.     return ObjTrue;
  2150. }
  2151.  
  2152. static ObjPtr ShowFrontSpacePanelControls(spacePanel, windowName)
  2153. ObjPtr spacePanel;
  2154. char *windowName;
  2155. /*Makes a new control window to control a space panel*/
  2156. {
  2157.     WinInfoPtr controlWindow;
  2158.     ObjPtr var;
  2159.     ObjPtr panel;
  2160.     ObjPtr corral;
  2161.     ObjPtr contents;
  2162.     real rgb[3], hsv[3];
  2163.     WinInfoPtr dialogExists;
  2164.  
  2165.     dialogExists = DialogExists((WinInfoPtr) spacePanel, NewString("Controls"));
  2166.     controlWindow = GetDialog((WinInfoPtr) spacePanel, NewString("Controls"), windowName, 
  2167.     SPWINWIDTH, SPWINHEIGHT, SPWINWIDTH,
  2168.     SPWINHEIGHT, WINUI + WINFIXEDSIZE);
  2169.     
  2170.     if (!dialogExists)
  2171.     {
  2172.     long info;
  2173.     ObjPtr value;
  2174.     
  2175.     ObjPtr checkBox, icon, name, colorBar, titleBox, textBox, button;
  2176.     ObjPtr colorWheel, slider, radioGroup;
  2177.     int left, right, bottom, top;
  2178.  
  2179.     SetVar((ObjPtr) controlWindow, REPOBJ, spacePanel);
  2180.  
  2181.     /*Set help string*/
  2182.     SetVar((ObjPtr) controlWindow, HELPSTRING, NewString("This window \
  2183. shows controls for a space panel.  For information about any of the controls \
  2184. in the window, use Help In Context on the control.\n"));
  2185.  
  2186.     /*Add in a panel*/
  2187.     panel = NewPanel(greyPanelClass, 0, SPWINWIDTH, 0, SPWINHEIGHT);
  2188.     if (!panel)
  2189.     {
  2190.         return ObjFalse;
  2191.     }
  2192.     contents = GetVar((ObjPtr) controlWindow, CONTENTS);
  2193.     PrefixList(contents, panel);
  2194.     SetVar(panel, PARENT, (ObjPtr) controlWindow);
  2195.  
  2196.     contents = GetVar(panel, CONTENTS);
  2197.  
  2198.     /*Add in the group of controls for text color*/
  2199.     left = MAJORBORDER;
  2200.     top = SPWINHEIGHT - MAJORBORDER;
  2201.     right = SPWINWIDTH - MAJORBORDER;
  2202.     bottom = SPWINHEIGHT - (MAJORBORDER + (COLORWHEELWIDTH + TEXTBOXSEP + TEXTBOXHEIGHT + CHECKBOXHEIGHT + TITLEBOXTOP + 3 * MINORBORDER))
  2203. ;
  2204.  
  2205.     titleBox = NewTitleBox(left, right, bottom, top, "Background");
  2206.     PrefixList(contents, titleBox);
  2207.     SetVar(titleBox, PARENT, panel);
  2208.  
  2209.     left += MINORBORDER;
  2210.     right -= MINORBORDER;
  2211.     top -= MINORBORDER + TITLEBOXTOP;
  2212.     
  2213.  
  2214.     /*Make the color wheel*/
  2215.     colorWheel = NewColorWheel(left, left + COLORWHEELWIDTH,
  2216.             top - COLORWHEELWIDTH, top, "Background Color");
  2217.     SetVar(colorWheel, PARENT, panel);
  2218.     PrefixList(contents, colorWheel);
  2219.     AssocColorControlWithVar(colorWheel, spacePanel, BACKGROUND);
  2220.     SetVar(colorWheel, HELPSTRING, NewString("This color wheel controls the \
  2221. hue and saturation of the color used to draw the background of the space panel.  \
  2222. The final color is a combination of this hue and saturation and the value, or brightness, \
  2223. given by the Value slider."));
  2224.     
  2225.     /*Make the text box below*/
  2226.     textBox = NewTextBox(left, left + COLORWHEELWIDTH,
  2227.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  2228.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  2229.             PLAIN, "Background Color Label", "Color");
  2230.     SetVar(textBox, PARENT, panel);
  2231.     PrefixList(contents, textBox);
  2232.     SetTextAlign(textBox, CENTERALIGN);
  2233.  
  2234.     /*Make the brightness slider*/
  2235.     slider = NewSlider(right - SLIDERWIDTH, right, 
  2236.                top - COLORWHEELWIDTH, top,
  2237.                PLAIN, "Background Value");
  2238.     SetVar(slider, PARENT, panel);
  2239.     PrefixList(contents, slider);
  2240.     SetSliderRange(slider, 1.0, 0.0, 0.0);
  2241.     AssocBrightnessControlWithVar(slider, spacePanel, BACKGROUND);
  2242.     SetVar(slider, HELPSTRING, NewString("This slider controls the \
  2243. value, or brightness, of the color used to draw the background of the space panel.  \
  2244. The final color is a combination of this value and the hue and saturation \
  2245. given by the Color color wheel."));
  2246.  
  2247.     /*Make the text box below*/
  2248.     textBox = NewTextBox(right - SLIDERWIDTH - MAJORBORDER, right + MAJORBORDER,
  2249.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  2250.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  2251.             PLAIN, "Text Value Label", "Value");
  2252.     SetVar(textBox, PARENT, panel);
  2253.     PrefixList(contents, textBox);
  2254.     SetTextAlign(textBox, CENTERALIGN);
  2255.  
  2256.     /*Make the check box*/
  2257.     top -= COLORWHEELWIDTH + TEXTBOXSEP + TEXTBOXHEIGHT + MINORBORDER;
  2258.     checkBox = NewCheckBox(left, right, 
  2259.         top - CHECKBOXHEIGHT, top,
  2260.         "No Background", true);
  2261.     SetVar(checkBox, PARENT, panel);
  2262.     PrefixList(contents, checkBox);
  2263.     AssocInhibitControlWithVar(checkBox, spacePanel, BACKGROUND, NewInt(UIBLACK));
  2264.     SetVar(checkBox, HELPSTRING, NewString("This checkbox controls whether \
  2265. a background is shown.  If it is selected, no background is shown, and the \
  2266. objects behind can be seen."));
  2267.  
  2268.     /*Make check box for show grid*/
  2269.     left = MAJORBORDER;
  2270.     top = MAJORBORDER + CHECKBOXHEIGHT;
  2271.     right = SPWINWIDTH - MAJORBORDER;
  2272.     bottom = MAJORBORDER;
  2273.  
  2274.     checkBox = NewCheckBox(left, right, bottom, top, "Show grid",
  2275.             GetPredicate(spacePanel, SHOWGRID));
  2276.     PrefixList(contents, checkBox);
  2277.     SetVar(checkBox, PARENT, panel);
  2278.     if (!GetVar(spacePanel, SHOWGRID)) SetVar(spacePanel, SHOWGRID, NewInt(0));
  2279.     AssocDirectControlWithVar(checkBox, spacePanel, SHOWGRID);
  2280.     }
  2281.     return (ObjPtr) controlWindow;
  2282. }
  2283.  
  2284. static ObjPtr ShowBackSpacePanelControls(spacePanel, windowName)
  2285. ObjPtr spacePanel;
  2286. char *windowName;
  2287. /*Makes a new control window to control a space panel*/
  2288. {
  2289.     WinInfoPtr controlWindow;
  2290.     ObjPtr var;
  2291.     ObjPtr panel;
  2292.     ObjPtr corral;
  2293.     ObjPtr contents;
  2294.     real rgb[3], hsv[3];
  2295.     WinInfoPtr dialogExists;
  2296.  
  2297.     dialogExists = DialogExists((WinInfoPtr) spacePanel, NewString("Controls"));
  2298.     controlWindow = GetDialog((WinInfoPtr) spacePanel, NewString("Controls"), windowName, 
  2299.     SPWINWIDTH, SPWINHEIGHT, SPWINWIDTH,
  2300.     SPWINHEIGHT, WINUI + WINFIXEDSIZE);
  2301.     
  2302.     if (!dialogExists)
  2303.     {
  2304.     long info;
  2305.     ObjPtr value;
  2306.     
  2307.     ObjPtr checkBox, icon, name, colorBar, titleBox, textBox, button;
  2308.     ObjPtr colorWheel, slider, radioGroup;
  2309.     int left, right, bottom, top;
  2310.  
  2311.     SetVar((ObjPtr) controlWindow, REPOBJ, spacePanel);
  2312.  
  2313.     /*Set help string*/
  2314.     SetVar((ObjPtr) controlWindow, HELPSTRING, NewString("This window \
  2315. shows controls for a space panel.  For information about any of the controls \
  2316. in the window, use Help In Context on the control.\n"));
  2317.  
  2318.     /*Add in a panel*/
  2319.     panel = NewPanel(greyPanelClass, 0, SPWINWIDTH, 0, SPWINHEIGHT);
  2320.     if (!panel)
  2321.     {
  2322.         return ObjFalse;
  2323.     }
  2324.     contents = GetVar((ObjPtr) controlWindow, CONTENTS);
  2325.     PrefixList(contents, panel);
  2326.     SetVar(panel, PARENT, (ObjPtr) controlWindow);
  2327.  
  2328.     contents = GetVar(panel, CONTENTS);
  2329.  
  2330.     /*Add in the group of controls for text color*/
  2331.     left = MAJORBORDER;
  2332.     top = SPWINHEIGHT - MAJORBORDER;
  2333.     right = SPWINWIDTH - MAJORBORDER;
  2334.     bottom = SPWINHEIGHT - (MAJORBORDER + (COLORWHEELWIDTH +
  2335.         TEXTBOXSEP + TEXTBOXHEIGHT + CHECKBOXHEIGHT + TITLEBOXTOP + 3 * MINORBORDER));
  2336.  
  2337.     titleBox = NewTitleBox(left, right, bottom, top, "Background");
  2338.     PrefixList(contents, titleBox);
  2339.     SetVar(titleBox, PARENT, panel);
  2340.  
  2341.     left += MINORBORDER;
  2342.     right -= MINORBORDER;
  2343.     top -= MINORBORDER + TITLEBOXTOP;
  2344.     
  2345.     /*Make the color wheel*/
  2346.     colorWheel = NewColorWheel(left, left + COLORWHEELWIDTH,
  2347.             top - COLORWHEELWIDTH, top, "Background Color");
  2348.     SetVar(colorWheel, PARENT, panel);
  2349.     PrefixList(contents, colorWheel);
  2350.     AssocColorControlWithVar(colorWheel, spacePanel, BACKGROUND);
  2351.     SetVar(colorWheel, HELPSTRING, NewString("This color wheel controls the \
  2352. hue and saturation of the color used to draw the background of the space panel.  \
  2353. The final color is a combination of this hue and saturation and the value, or brightness, \
  2354. given by the Value slider."));
  2355.     
  2356.     /*Make the text box below*/
  2357.     textBox = NewTextBox(left, left + COLORWHEELWIDTH,
  2358.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  2359.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  2360.             PLAIN, "Background Color Label", "Color");
  2361.     SetVar(textBox, PARENT, panel);
  2362.     PrefixList(contents, textBox);
  2363.     SetTextAlign(textBox, CENTERALIGN);
  2364.  
  2365.     /*Make the brightness slider*/
  2366.     slider = NewSlider(right - SLIDERWIDTH, right, 
  2367.                top - COLORWHEELWIDTH, top,
  2368.                PLAIN, "Background Value");
  2369.     SetVar(slider, PARENT, panel);
  2370.     PrefixList(contents, slider);
  2371.     SetSliderRange(slider, 1.0, 0.0, 0.0);
  2372.     AssocBrightnessControlWithVar(slider, spacePanel, BACKGROUND);
  2373.     SetVar(slider, HELPSTRING, NewString("This slider controls the \
  2374. value, or brightness, of the color used to draw the background of the space panel.  \
  2375. The final color is a combination of this value and the hue and saturation \
  2376. given by the Color color wheel."));
  2377.  
  2378.     /*Make the text box below*/
  2379.     textBox = NewTextBox(right - SLIDERWIDTH - MAJORBORDER, right + MAJORBORDER,
  2380.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  2381.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  2382.             PLAIN, "Text Value Label", "Value");
  2383.     SetVar(textBox, PARENT, panel);
  2384.     PrefixList(contents, textBox);
  2385.     SetTextAlign(textBox, CENTERALIGN);
  2386.  
  2387.     /*Cross link the slider and color wheel*/
  2388.     SetVar(colorWheel, SLIDER, slider);
  2389.     SetVar(slider, COLORWHEEL, colorWheel);
  2390.  
  2391.     /*Make check box for show grid*/
  2392.     left = MAJORBORDER;
  2393.     top = MAJORBORDER + CHECKBOXHEIGHT;
  2394.     right = SPWINWIDTH - MAJORBORDER;
  2395.     bottom = MAJORBORDER;
  2396.  
  2397.     checkBox = NewCheckBox(left, right, bottom, top, "Show grid",
  2398.             GetPredicate(spacePanel, SHOWGRID));
  2399.     PrefixList(contents, checkBox);
  2400.     SetVar(checkBox, PARENT, panel);
  2401.     if (!GetVar(spacePanel, SHOWGRID)) SetVar(spacePanel, SHOWGRID, NewInt(0));
  2402.     AssocDirectControlWithVar(checkBox, spacePanel, SHOWGRID);
  2403.     }
  2404.     return (ObjPtr) controlWindow;
  2405. }
  2406.  
  2407. static ObjPtr ChangeSpaceTools(toolGroup)
  2408. ObjPtr toolGroup;
  2409. /*Changes a space's tools based on toolGroup*/
  2410. {
  2411.     ObjPtr value;
  2412.     int oldValue, newValue, index;
  2413.     ObjPtr space;
  2414.     ObjPtr contents;
  2415.     ObjPtr var;
  2416.     ThingListPtr runner;
  2417.  
  2418.     space = GetObjectVar("ChangeSpaceTools", toolGroup, SPACE);
  2419.     if (!space)
  2420.     {
  2421.     return ObjFalse;
  2422.     }
  2423.     value = GetVar(space, EDITTOOL);
  2424.     if (value) 
  2425.     {
  2426.     oldValue = GetInt(value);
  2427.     }
  2428.     else
  2429.     {
  2430.     oldValue = -1;
  2431.     }
  2432.  
  2433.     value = GetValue(toolGroup);
  2434.     if (value) 
  2435.     {
  2436.     index = GetInt(value);
  2437.     }
  2438.     else
  2439.     {
  2440.     index = 0;
  2441.     }
  2442.  
  2443.     newValue = ST_FINGER;
  2444.     contents = GetListVar("ChangeSpaceTools", toolGroup, CONTENTS);
  2445.     runner = LISTOF(contents);
  2446.     while (runner)
  2447.     {
  2448.     if (!index)
  2449.     {
  2450.         /*Found it*/
  2451.         var = GetVar(runner -> thing, EDITTOOL);
  2452.         if (var)
  2453.         {
  2454.         newValue = GetInt(var);
  2455.         }
  2456.         break;
  2457.     }
  2458.     --index;
  2459.     runner = runner -> next;
  2460.     }
  2461.  
  2462.     if (oldValue == newValue)
  2463.     {
  2464.     return ObjFalse;
  2465.     }
  2466.  
  2467.     if (oldValue == ST_FLYING)
  2468.     {
  2469.     /*Transition from flying*/
  2470.     ObjPtr observer;
  2471.     ObjPtr var;
  2472.     real forward[3], up[3], side[3];
  2473.  
  2474.     observer = GetVar(space, OBSERVER);
  2475.     if (observer)
  2476.     {
  2477.         /*Incorporate changes*/
  2478.         real newRot[3][3];
  2479.          Quaternion rotQuat;
  2480.  
  2481.         GetAdjustedVectors(forward, up, observer);
  2482.         CROSS(forward, up, side);
  2483.  
  2484.         /*Make a matrix*/
  2485.         newRot[0][0] = side[0];
  2486.         newRot[1][0] = side[1];
  2487.         newRot[2][0] = side[2];
  2488.  
  2489.         newRot[0][1] = up[0];
  2490.         newRot[1][1] = up[1];
  2491.         newRot[2][1] = up[2];
  2492.  
  2493.         newRot[0][2] = -forward[0];
  2494.         newRot[1][2] = -forward[1];
  2495.         newRot[2][2] = -forward[2];
  2496.  
  2497.         MatrixToQuaternion(newRot, rotQuat);
  2498.         var = NewRealArray(1, 4L);
  2499.         CArray2Array(var, rotQuat);
  2500.         SetVar(observer, ROTQUAT, var);
  2501.  
  2502.         SetVar(observer, ROLL, NULLOBJ);
  2503.         SetVar(observer, PITCH, NULLOBJ);
  2504.         SetVar(observer, AIRSPEED, NULLOBJ);
  2505.         SetVar(observer, FLYING, ObjFalse);
  2506.  
  2507.         LogObserver(observer);
  2508.     }
  2509.     }
  2510.  
  2511.     if (newValue == ST_FLYING)
  2512.     {
  2513.     /*Transition from flying*/
  2514.     ObjPtr observer;
  2515.     ObjPtr var;
  2516.  
  2517.     observer = GetVar(space, OBSERVER);
  2518.     if (observer)
  2519.     {
  2520.         /*Incorporate changes*/
  2521.         SetVar(observer, ROLL, NewReal(0.0));
  2522.         SetVar(observer, PITCH, NewReal(0.0));
  2523.         SetVar(observer, AIRSPEED, NewReal(4.0 * AIRSPEEDFACTOR));
  2524.  
  2525.         LogObserver(observer);
  2526.     }
  2527.     }
  2528.  
  2529.     SetVar(space, EDITTOOL, NewInt(newValue));
  2530.     return ObjTrue;
  2531. }
  2532.  
  2533. ObjPtr ReshapeVisWindow(window, ol, or, ob, ot, nl, nr, nb, nt)
  2534. ObjPtr window;
  2535. int ol, or, ob, ot;
  2536. int nl, nr, nb, nt;
  2537. /*Reshapes vis window given that ol, or, ob, and ot was the old
  2538.   viewport.  Does not redraw anything.*/
  2539. {
  2540.     ObjPtr contents;
  2541.  
  2542.     /*DIKEO reshape the space window, if any*/
  2543.  
  2544.     contents = GetVar(window, CONTENTS);
  2545.     if (contents && IsList(contents))
  2546.     {
  2547.     ReshapeList(LISTOF(contents),
  2548.         0, or - ol, 0, ot - ob,
  2549.         0, nr - nl, 0, nt - nb);
  2550.     }   
  2551.     return ObjTrue;
  2552. }
  2553.  
  2554. #ifdef CHANGECURSOR
  2555. static Bool metering;
  2556. static Bool pointCurrently;
  2557. static real meterX, meterY, meterZ;
  2558. static ObjPtr meterObject;
  2559.  
  2560. static ObjPtr IdleVisWindowCursor(visWindow, x, y)
  2561. ObjPtr visWindow;
  2562. int x, y;
  2563. /*Idles a vis window with a cursor inside*/
  2564. {
  2565. #ifdef GRAPHICS
  2566.     ObjPtr space, var;
  2567.     int left, right, bottom, top;
  2568.     ObjPtr contents;
  2569.     ThingListPtr runner;
  2570.     FuncTyp method;
  2571.  
  2572.     space = GetVar(visWindow, SPACE);
  2573.     if (!space)
  2574.     {
  2575.     return ObjFalse;
  2576.     }
  2577.  
  2578.     var = GetVar(space, EDITTOOL);
  2579.     if (!var)
  2580.     {
  2581.     return ObjFalse;
  2582.     }
  2583.  
  2584.     if (GetInt(var) == ST_FINGER)
  2585.     {
  2586.     FuncTyp method;
  2587.     /*Have to go through the space to find where this is picked*/
  2588.     Get2DIntBounds(space, &left, &right, &bottom, &top);
  2589.  
  2590.     StartSpace(space, left, right, bottom, top, PICKSPACE, 0);
  2591.     
  2592.     /*Pick the contents of the space*/
  2593.     contents = GetVar(space, CONTENTS);
  2594.     
  2595.     runner = LISTOF(contents);
  2596.     while (runner)
  2597.     {
  2598.         if (IsObject(runner -> thing))
  2599.         {
  2600.         PickObject(runner -> thing, PR_CENTER);
  2601.         method = GetMethod(runner -> thing, PICKPOINT);
  2602.         if (method)
  2603.         {
  2604.             (*method)(runner -> thing);
  2605.         }
  2606.         }
  2607.         runner = runner -> next;
  2608.     }
  2609.     
  2610.     StopSpace(PICKSPACE);
  2611.     
  2612.     if (spacePickedObject && (bestPickVertex >= 0))
  2613.     {
  2614.         /*There is a vertex to highlight*/
  2615.         method = GetMethod(spacePickedObject,
  2616.                 BEGINSTUFFING);
  2617.         if (method)
  2618.         {
  2619.         (*method)(spacePickedObject);
  2620.         method = GetMethod(spacePickedObject,
  2621.             STUFFSELPOINT);
  2622.         if (method)
  2623.         {
  2624.             real px, py, pz;
  2625.             real xnew, ynew, znew, wnew;
  2626.  
  2627.             Matrix projMatrix, viewMatrix, curMatrix;
  2628.             (*method)(spacePickedObject,
  2629.                 bestPickVertex, &px, &py, &pz);
  2630.  
  2631.             StartSpace(space, left, right, bottom, top, OVERDRAWSPACE, 0);
  2632.             mmode(MPROJECTION);
  2633.             getmatrix(projMatrix);
  2634.             mmode(MVIEWING);
  2635.             getmatrix(viewMatrix);
  2636.             MULTMATRIX(viewMatrix, projMatrix, curMatrix);
  2637.             StopSpace(OVERDRAWSPACE);
  2638.  
  2639.             xnew = px * curMatrix[0][0] + py * curMatrix[1][0] +
  2640.                pz * curMatrix[2][0] +      curMatrix[3][0];
  2641.  
  2642.             ynew = px * curMatrix[0][1] + py * curMatrix[1][1] +
  2643.                pz * curMatrix[2][1] +      curMatrix[3][1];
  2644.  
  2645.             znew = px * curMatrix[0][2] + py * curMatrix[1][2] +
  2646.                pz * curMatrix[2][2] +      curMatrix[3][2];
  2647.  
  2648.             wnew = px * curMatrix[0][3] + py * curMatrix[1][3] +
  2649.                pz * curMatrix[2][3] +      curMatrix[3][3];
  2650.  
  2651.             xnew /= wnew;
  2652.             ynew /= wnew;
  2653.             znew /= wnew;
  2654.             SetSubPort(left, right, bottom, top);
  2655.             mmode(MPROJECTION);
  2656.             ortho2(-1.0, 1.0, -1.0, 1.0);
  2657.             mmode(MVIEWING);
  2658.             loadmatrix(Identity);
  2659.             OverDraw(true);
  2660.             EraseAll();
  2661.             SetUIColor(UIWHITE);
  2662.             DrawSpaceLine(-1.0, ynew, 0.0, 1.0, ynew, 0.0);
  2663.             DrawSpaceLine(xnew, -1.0, 0.0, xnew, 1.0, 0.0);
  2664.             OverDraw(false);
  2665.             RestoreSubPort();
  2666.         }
  2667.         }
  2668.     }
  2669.     else
  2670.     {
  2671.         SetSubPort(left, right, bottom, top);
  2672.         OverDraw(true);
  2673.         EraseAll();
  2674.         OverDraw(false);
  2675.         RestoreSubPort();
  2676.     }
  2677.     }
  2678. #endif
  2679.     return ObjTrue;
  2680. }
  2681.  
  2682. static ObjPtr EnterVisWindow(visWindow)
  2683. ObjPtr visWindow;
  2684. /*Enters a vis window*/
  2685. {
  2686.     metering = true;
  2687.     pointCurrently = false;
  2688. }
  2689.  
  2690. static ObjPtr LeaveVisWindow(visWindow)
  2691. ObjPtr visWindow;
  2692. /*Leaves a vis window*/
  2693. {
  2694.     if (metering && pointCurrently)
  2695.     {
  2696.     OverDraw(true);
  2697.     EraseAll();
  2698.     OverDraw(false);
  2699.     }
  2700.     metering = false;
  2701. }
  2702. #endif
  2703.  
  2704. static ObjPtr WinPhscScreen(win)
  2705. ObjPtr win;
  2706. /*Makes the current window go to the phscologram screen*/
  2707. {
  2708.     SetWindowPosition(0, 1100, 0, 615);
  2709.     phsco = true;
  2710.     return ObjTrue;
  2711. }
  2712.  
  2713.  
  2714.  
  2715. WinInfoPtr NewVisWindow(title, flags)
  2716. char *title;
  2717. long flags;
  2718. /*Creates a new visualization window with title title and flags flags*/
  2719. {
  2720.     WinInfoPtr visWindow;
  2721.     WinInfoPtr spaceWindow;
  2722.     ObjPtr space, panel, corral, contents, panelContents;
  2723.     ObjPtr button, radioGroup;
  2724.     int l, r, b, t;
  2725.     ObjPtr lights;
  2726.     ThingListPtr runner;
  2727.     ObjPtr spaceContents;
  2728.  
  2729.     visWindow = NewObjWindow(visWindowClass, title, 
  2730.     rgbGoodForUI ? flags : flags & ~WINRGB,
  2731.     VWINWIDTH, VWINHEIGHT, SCRWIDTH, SCRHEIGHT);
  2732.  
  2733. #ifdef CHANGECURSOR
  2734.     SetMethod((ObjPtr) visWindow, IDLECURSOR, IdleVisWindowCursor);
  2735.     SetMethod((ObjPtr) visWindow, ENTERCURSOR, EnterVisWindow);
  2736.     SetMethod((ObjPtr) visWindow, LEAVECURSOR, LeaveVisWindow);
  2737. #endif
  2738.  
  2739.     SetMinSize(visWindow, 100, 100);
  2740.  
  2741.     contents = GetVar((ObjPtr) visWindow, CONTENTS);
  2742.  
  2743.     /*Create the space and its associated panels*/
  2744.     l = VWINTOOLPWIDTH;
  2745.     r = VWINWIDTH - VWINPANELWIDTH;
  2746.     b = 0;
  2747.     t = VWINHEIGHT;
  2748.  
  2749.     if (rgbGoodForUI)
  2750.     {
  2751.     spaceWindow = visWindow;
  2752.     }
  2753.     else
  2754.     {
  2755.     char newName[300];
  2756.     int x, y;
  2757.     ObjPtr var;
  2758.     real margins[4];
  2759.     ObjPtr panelContents, textBox;
  2760.  
  2761.     GetWindowOrigin(&x, &y);
  2762.     spaceWindow = NewObjWindow(spaceWindowClass, title,
  2763.         flags | WINFIXEDLOC | WINRGB | WINNOFRAME,
  2764.         r - l, t - b, x + l, y);
  2765.  
  2766.     SetVar((ObjPtr) visWindow, SPACEWINDOW, (ObjPtr) spaceWindow);
  2767.     var = NewList();
  2768.     PrefixList(var, (ObjPtr) spaceWindow);
  2769.     SetVar((ObjPtr) visWindow, SUBWINDOWS, var);
  2770.     SetVar((ObjPtr) spaceWindow, SUPERWINDOW, (ObjPtr) visWindow);
  2771.     margins[0] = (real) (l);
  2772.     margins[1] = (real) (VWINWIDTH - r);
  2773.     margins[2] = 0.0;
  2774.     margins[3] = 0.0;
  2775.     var = NewRealArray(1, 4L);
  2776.     CArray2Array(var, margins);
  2777.     SetVar((ObjPtr) spaceWindow, SUBWINDOWMARGIN, var);
  2778.  
  2779.     /*Make a dummy panel to put here*/
  2780.     panel = NewPanel(greyPanelClass, l, r, b, t);
  2781.     if (!panel)
  2782.     {
  2783.         return (WinInfoPtr) 0;
  2784.     }
  2785.     SetVar(panel, PARENT, (ObjPtr) visWindow);
  2786.     PrefixList(contents, panel);
  2787.     panelContents = GetVar(panel, CONTENTS);
  2788.     
  2789.     r = r - l;
  2790.     l = 0;
  2791.     t = t - b;
  2792.     b = 0;
  2793.  
  2794.     /*And a warning text box*/
  2795.     textBox = NewTextBox(MAJORBORDER, r - MAJORBORDER, MAJORBORDER,
  2796.         t - MAJORBORDER, 0, "Yaha",
  2797. "In normal operation, you should never see this message.  If you can read this, it means \
  2798. that something has gone wrong with the way SciAn is stacking its windows.  This is most likely due \
  2799. to an X windows operation on the windows that SciAn cannot detect.\n\n\
  2800. You can probably fix the \
  2801. problem for the time being simply by clicking in the title bar of this window \
  2802. to pop it to the top.\n\n\
  2803. Please report this bug to scian-bugs@scri.fsu.edu.");
  2804.     PrefixList(panelContents, textBox);
  2805.     SetVar(textBox, PARENT, panel);
  2806.     }
  2807.     spaceContents = GetVar((ObjPtr) spaceWindow, CONTENTS);
  2808.  
  2809.     /*Add in the panel behind the space*/
  2810.     panel = NewPanel(spaceBackPanelClass, l, r, b, t);
  2811.     if (!panel)
  2812.     {
  2813.     return (WinInfoPtr) 0;
  2814.     }
  2815.     SetVar(panel, NAME, ConcatStrings(NewString(title), NewString(" Back Panel")));
  2816.     SetVar(panel, STICKINESS, NewInt(STICKYLEFT + STICKYRIGHT +
  2817.                      STICKYBOTTOM + STICKYTOP));
  2818.     SetVar(panel, TYPESTRING, NewString("panel"));
  2819.     SetVar(panel, HELPSTRING, NewString("This panel holds 2-dimensional objects \
  2820. and is always drawn behind the space."));
  2821.     SetVar(panel, OWNERWINDOW, (ObjPtr) spaceWindow);
  2822. #ifdef INTERACTIVE
  2823.     SetMethod(panel, PRESS, PressSpacePanel);
  2824. #endif
  2825. #ifndef BOCKA
  2826.     PrefixList(spaceContents, panel);
  2827. #endif
  2828.     
  2829.     /*Add in a space*/
  2830.     space = NewSpace(l, r, b, t);
  2831.     if (!space)
  2832.     {
  2833.     return (WinInfoPtr) 0;
  2834.     }
  2835.     SetVar(space, STICKINESS, NewInt(STICKYLEFT + STICKYRIGHT +
  2836.                      STICKYBOTTOM + STICKYTOP));
  2837.     SetVar(space, NAME, ConcatStrings(NewString(title), NewString(" Space")));
  2838.     SetVar(space, OWNERWINDOW, (ObjPtr) spaceWindow);
  2839.     PrefixList(spaceContents, space);
  2840.     SetVar(space, PARENT, (ObjPtr) spaceWindow);
  2841.  
  2842.     /*Notify the space that the panel is behind the space*/
  2843.     SetVar(panel, SPACE, space);
  2844.     SetVar(space, BACKPANEL, panel);
  2845.     SetVar(panel, PARENT, space);
  2846.     SetMethod(panel, NEWCTLWINDOW, ShowBackSpacePanelControls);
  2847.     SetMethod(panel, SHOWCONTROLS, NewControlWindow);
  2848.  
  2849.     /*Add in the panel to cover the space*/
  2850.     panel = NewPanel(spacePanelClass,  l, r, b, t);
  2851.     if (!panel)
  2852.     {
  2853.     return (WinInfoPtr) 0;
  2854.     }
  2855.     SetVar(panel, NAME, ConcatStrings(NewString(title), NewString(" Front Panel")));
  2856.     SetVar(panel, STICKINESS, NewInt(STICKYLEFT + STICKYRIGHT +
  2857.                      STICKYBOTTOM + STICKYTOP));
  2858.     SetVar(panel, TYPESTRING, NewString("panel"));
  2859.     SetVar(panel, HELPSTRING, NewString("This panel holds 2-dimensional objects \
  2860. and is always drawn in front of the space."));
  2861.     SetVar(panel, OWNERWINDOW, (ObjPtr) spaceWindow);
  2862.     SetVar(panel, SPACE, space);
  2863. #ifdef INTERACTIVE
  2864.     SetMethod(panel, PRESS, PressSpacePanel);
  2865. #endif
  2866. #ifndef BOCKA
  2867.     PrefixList(spaceContents, panel);
  2868. #endif
  2869.     SetVar(panel, PARENT, space);
  2870.  
  2871.     /*Notify the space that the panel covers the space*/
  2872.     SetVar(space, FRONTPANEL, panel);
  2873.     SetVar(panel, FRONTPANEL, ObjTrue);
  2874.     SetMethod(panel, NEWCTLWINDOW, ShowFrontSpacePanelControls);
  2875.     SetMethod(panel, SHOWCONTROLS, NewControlWindow);
  2876.  
  2877.     /*Give the space to (potentially) both the windows*/
  2878.     SetVar((ObjPtr) visWindow, SPACE, space);
  2879.     SetVar((ObjPtr) spaceWindow, SPACE, space);
  2880.  
  2881.     /*Add in a tools panel*/
  2882.     panel = NewPanel(greyPanelClass, 0, VWINTOOLPWIDTH, 0, VWINHEIGHT);
  2883.     if (!panel)
  2884.     {
  2885.     return (WinInfoPtr) 0;
  2886.     }
  2887.     SetVar(panel, STICKINESS, NewInt(STICKYLEFT + STICKYBOTTOM + STICKYTOP));
  2888. #ifndef BOCKA
  2889.     PrefixList(contents, panel);
  2890. #endif
  2891.     SetVar(panel, PARENT, (ObjPtr) visWindow);
  2892.     SetVar(space, TOOLPANEL, panel);
  2893.     SetVar(panel, TYPESTRING, NewString("panel"));
  2894.     SetVar(panel, HELPSTRING, NewString("You can show or hide this panel by choosing the Toggle Panel \
  2895. item from the Windows menu."));
  2896.     panelContents = GetVar(panel, CONTENTS);
  2897.  
  2898.     /*Put tools in the space tools group*/
  2899.     radioGroup = NewRadioButtonGroup("Space Tools");
  2900.     SetVar(space, TOOLGROUP, radioGroup);
  2901.     SetVar(radioGroup, HELPSTRING,
  2902.        NewString("This is a group of tools that allow you to modify the \
  2903. space using the mouse.  To use one of these tools, click on the icon representing \
  2904. the tool before clicking in the space.  To find out what each tool does, use \
  2905. help in context on each individual button."));
  2906.     SetVar(radioGroup, PARENT, panel);
  2907.     PrefixList(panelContents, radioGroup);
  2908.     SetVar(radioGroup, HALTHELP, ObjTrue);
  2909.     SetVar(radioGroup, STICKINESS, NewInt(STICKYLEFT + STICKYTOP));
  2910.  
  2911.     /*First the 3-D tools on the left*/
  2912.     l = VWTOOLBORDER;
  2913.     t = VWINHEIGHT - VWTOOLBORDER;
  2914.  
  2915.     /*Space finger tool*/
  2916.     button = NewIconButton(l, l + SMALLICONBUTTONSIZE,
  2917.             t - SMALLICONBUTTONSIZE, t,
  2918.             ICON3DFINGER, UIYELLOW, "Space Selection", BS_PLAIN);
  2919.     SetVar(button, STICKINESS, NewInt(STICKYLEFT + STICKYTOP));
  2920.     AddRadioButton(radioGroup, button);
  2921.     SetVar(button, HELPSTRING, NewString("This button chooses the space and space panel selection tool.\n\
  2922. \n\
  2923. Click and drag within the space using the center mouse button to rotate \
  2924. the entire space around the focus point of the observer at the center of the \
  2925. space.  The space can be rotated around any axis.  Hold down the Shift key \
  2926. to constrain to rotation around a principal axis of the space.  Double-click \
  2927. to snap the space to the nearest straight-on orientation.  \
  2928. If Space Rotation Guides is turned on in the space control panel, you will see the \
  2929. virtual trackball as a wire frame sphere.  If Rotation Inertia \
  2930. is turned on in the space control panel, the space will continue to rotate if you \
  2931. give it a spin and let go while moving the mouse.\n\
  2932. \n\
  2933. Click on an object within the space to select it.  Drag after clicking to move \
  2934. the objects in the space.  If you hold down the shift key while dragging, motion \
  2935. will be constrained to one principal axis of the space.\n\
  2936. \n\
  2937. Both rotation and motion will affect other spaces controlled by the same observer.  This \
  2938. is because rotation and motion actually change the position of the observer \
  2939. within the space.\n\
  2940. \n\
  2941. Click on a 2-D object in the front or back panel, such as a text box or line, \
  2942. to select it.  Once an object is selected, an outline with handles will appear \
  2943. around the object.  You can click and drag the handled to move and resize the \
  2944. object.  You can also edit text within text objects by clicking and dragging."));
  2945.     SetVar(button, EDITTOOL, NewInt(ST_FINGER));
  2946.  
  2947.     t = t - SMALLICONBUTTONSIZE - VWTOOLBORDER;
  2948.  
  2949. #ifndef RELEASE
  2950.     /*Space finger tool*/
  2951.     button = NewIconButton(l, l + SMALLICONBUTTONSIZE,
  2952.             t - SMALLICONBUTTONSIZE, t,
  2953.             ICONQUESTION, UIYELLOW, "Eyedropper", BS_PLAIN);
  2954.     SetVar(button, STICKINESS, NewInt(STICKYLEFT + STICKYTOP));
  2955.     AddRadioButton(radioGroup, button);
  2956.     SetVar(button, HELPSTRING, NewString("This button chooses the space color eyedropper tool.\n\
  2957. \n\
  2958. Click within a space using this tool to copy the color under the arrow to the clipboard.  \
  2959. This color can then be pasted in any color or brightness control."));
  2960.     SetVar(button, EDITTOOL, NewInt(ST_EYEDROPPER));
  2961.  
  2962.     t = t - SMALLICONBUTTONSIZE - VWTOOLBORDER;
  2963. #endif
  2964.  
  2965.     /*Flight tool*/
  2966.     button = NewIconButton(l, l + SMALLICONBUTTONSIZE,
  2967.             t - SMALLICONBUTTONSIZE, t,
  2968.             ICONPLANE, UIYELLOW, "Flight Simulator", BS_PLAIN);
  2969.     SetVar(button, STICKINESS, NewInt(STICKYLEFT + STICKYTOP));
  2970.     AddRadioButton(radioGroup, button);
  2971.     SetVar(button, HELPSTRING, NewString("This button chooses the space flight \
  2972. simulator.  When this tool is chosen, you can fly through the space like an airplane \
  2973. using the mouse.  This works best when the window is resized to fill the entire \
  2974. screen.  It is also a good idea to give the observer a wide field of view from \
  2975. within the observer control panel.\n\
  2976. \n\
  2977. To start flying, click the left mouse button in the space.  Pull the mouse back \
  2978. toward you to climb and push it forward to dive.  Move the mouse to the left or right \
  2979. to turn.  To accelerate, press the up arrow key repeatedly.  To decelerate, press the \
  2980. down arrow key.  When you are done flying, press the left mouse button once more \
  2981. in the space."));
  2982.     SetVar(button, EDITTOOL, NewInt(ST_FLYING));
  2983.  
  2984.     t = t - SMALLICONBUTTONSIZE - VWTOOLBORDER;
  2985.  
  2986. #if 0
  2987.     /*3-D Finger Tool*/
  2988.     button = NewIconButton(l, l + SMALLICONBUTTONSIZE,
  2989.             t - SMALLICONBUTTONSIZE, t,
  2990.             ICON3DFINGER, UIYELLOW, "Space Selection", BS_PLAIN);
  2991.     SetVar(button, STICKINESS, NewInt(STICKYLEFT + STICKYTOP));
  2992.     AddRadioButton(radioGroup, button);
  2993.     SetVar(button, HELPSTRING, NewString("This button chooses the space \
  2994. selection tool.  Use the left mouse button with this tool to select \
  2995. visualization objects within the space.\n"));
  2996.     SetVar(button, EDITTOOL, NewInt(ST_3DFINGER));
  2997.  
  2998.     t = t - SMALLICONBUTTONSIZE - VWTOOLBORDER;
  2999. #endif
  3000.  
  3001. #if 0
  3002.     /*Meter tool*/
  3003.     button = NewIconButton(l, l + SMALLICONBUTTONSIZE,
  3004.             t - SMALLICONBUTTONSIZE, t,
  3005.             ICONMETER, UIYELLOW, "Data Meter", BS_PLAIN);
  3006.     SetVar(button, STICKINESS, NewInt(STICKYLEFT + STICKYTOP));
  3007.     AddRadioButton(radioGroup, button);
  3008.     SetVar(button, HELPSTRING, NewString("This button chooses the data meter \
  3009. tool, which is not implemented yet.\n"));
  3010.     SetVar(button, EDITTOOL, NewInt(ST_METER));
  3011.  
  3012.     t = t - SMALLICONBUTTONSIZE - VWTOOLBORDER;
  3013. #endif
  3014.  
  3015. #if 0
  3016.     /*Now the 3-D tools on the right*/
  3017.     l = 2 * VWTOOLBORDER + SMALLICONBUTTONSIZE;
  3018.     t = VWINHEIGHT - VWTOOLBORDER;
  3019.  
  3020.     /*2-D finger tool*/
  3021.     button = NewIconButton(l, l + SMALLICONBUTTONSIZE,
  3022.             t - SMALLICONBUTTONSIZE, t,
  3023.             ICONFINGER, UIYELLOW, "Panel Selection", BS_PLAIN);
  3024.     SetVar(button, STICKINESS, NewInt(STICKYLEFT + STICKYTOP));
  3025.     AddRadioButton(radioGroup, button);
  3026.     SetVar(button, HELPSTRING, NewString("This button chooses the space panel selection tool.\
  3027. Use this tool to select and move objects on the front or back panels of the space."));
  3028.     SetVar(button, EDITTOOL, NewInt(ST_FINGER));
  3029.  
  3030.     t = t - SMALLICONBUTTONSIZE - VWTOOLBORDER;
  3031. #endif
  3032.  
  3033.     /*Annotation tool*/
  3034.     button = NewIconButton(l, l + SMALLICONBUTTONSIZE,
  3035.             t - SMALLICONBUTTONSIZE, t,
  3036.             ICONANNOTATION, UIYELLOW, "Draw Annotation", BS_PLAIN);
  3037.     SetVar(button, STICKINESS, NewInt(STICKYLEFT + STICKYTOP));
  3038.     AddRadioButton(radioGroup, button);
  3039.     SetVar(button, HELPSTRING, NewString("This button chooses the annotation drawing tool.  \
  3040. Use this button to drag out annotation boxes on the panels of the space.  \
  3041. Normally this tool draws on the front panel.  Hold down the Alt or Ctrl key while drawing to draw \
  3042. on the back panel.  When the box has been drawn, enter text by typing.  The appearance of the boxes \
  3043. can be modified by selecting them and choosing Show Controls \
  3044. from the Objects menu."));
  3045.     SetVar(button, EDITTOOL, NewInt(ST_ANNOTATION));
  3046.  
  3047.     t = t - SMALLICONBUTTONSIZE - VWTOOLBORDER;
  3048.     button = NewIconButton(l, l + SMALLICONBUTTONSIZE,
  3049.             t - SMALLICONBUTTONSIZE, t,
  3050.             ICONRECTANGLE, UIYELLOW, "Draw Rectangle", BS_PLAIN);
  3051.     SetVar(button, STICKINESS, NewInt(STICKYLEFT + STICKYTOP));
  3052.     AddRadioButton(radioGroup, button);
  3053.     SetVar(button, HELPSTRING, NewString("This button chooses the rectangle drawing tool.  \
  3054. Use this button to drag out rectangular boxes on the panels of the space.  \
  3055. Normally this tool draws on the front panel.  Hold down the Alt or Ctrl key while drawing to draw \
  3056. on the back panel.  The appearance of the boxes can be modified by selecting them and choosing Show Controls \
  3057. from the Objects menu."));
  3058.     SetVar(button, EDITTOOL, NewInt(ST_RECTANGLE));
  3059.  
  3060.     t = t - SMALLICONBUTTONSIZE - VWTOOLBORDER;
  3061.     button = NewIconButton(l, l + SMALLICONBUTTONSIZE,
  3062.             t - SMALLICONBUTTONSIZE, t,
  3063.             ICONLINE, UIYELLOW, "Draw Line", BS_PLAIN);
  3064.     SetVar(button, STICKINESS, NewInt(STICKYLEFT + STICKYTOP));
  3065.     AddRadioButton(radioGroup, button);
  3066.     SetVar(button, HELPSTRING, NewString("This button chooses the line drawing tool.  \
  3067. Use this button to drag out lines on the panels of the space.  \
  3068. Normally this tool draws on the front panel.  Hold down the Alt or Ctrl key while drawing to draw \
  3069. on the back panel.  The appearance of the lines can be modified by selecting them and choosing Show Controls \
  3070. from the Objects menu.  You can also add arrowheads from within this control panel."));
  3071.     SetVar(button, EDITTOOL, NewInt(ST_LINE));
  3072.  
  3073.     t = t - SMALLICONBUTTONSIZE - VWTOOLBORDER;
  3074.     button = NewIconButton(l, l + SMALLICONBUTTONSIZE,
  3075.             t - SMALLICONBUTTONSIZE, t,
  3076.             ICONCLOCK, UIYELLOW, "Draw Time Readout", BS_PLAIN);
  3077.     SetVar(button, STICKINESS, NewInt(STICKYLEFT + STICKYTOP));
  3078.     AddRadioButton(radioGroup, button);
  3079.     SetVar(button, HELPSTRING, NewString("This button chooses the time readout drawing tool.  \
  3080. Use this button to drag out time readouts on the panels of the space.  The time readout is \
  3081. a text box which always shows the current time in the space.  To change the \
  3082. format in which the time is displayed, show the control panel by \
  3083. selecting the readout and choosing Show Controls from the Objects menu.  \
  3084. Normally this tool draws on the front panel.  Hold down the Alt or Ctrl key while drawing to draw \
  3085. on the back panel."));
  3086.     SetVar(button, EDITTOOL, NewInt(ST_TIME_READOUT));
  3087.  
  3088.     /*Give the radio group a default value*/
  3089.     SetValue(radioGroup, NewInt(ST_FINGER));
  3090.     SetVar(space, EDITTOOL, NewInt(ST_FINGER));
  3091.     SetVar(radioGroup, SPACE, space);
  3092.     SetMethod(radioGroup, CHANGEDVALUE, ChangeSpaceTools);
  3093.  
  3094.     /*Add in an object control panel*/
  3095.     panel = NewPanel(greyPanelClass, VWINWIDTH - VWINPANELWIDTH, VWINWIDTH, 
  3096.     0, VWINHEIGHT);
  3097.     if (!panel)
  3098.     {
  3099.     return (WinInfoPtr) 0;
  3100.     }
  3101.     SetVar(panel, STICKINESS, NewInt(STICKYRIGHT + STICKYBOTTOM + STICKYTOP));
  3102. #ifndef BOCKA
  3103.     PrefixList(contents, panel);
  3104. #endif
  3105.     SetVar(panel, PARENT, (ObjPtr) visWindow);
  3106.     SetVar(space, OBJPANEL, panel);
  3107.     SetVar(panel, TYPESTRING, NewString("panel"));
  3108.     SetVar(panel, HELPSTRING, NewString("You can show or hide this panel by choosing the Toggle Panel \
  3109. item from the Windows menu."));
  3110.  
  3111.     contents = GetVar(panel, CONTENTS);
  3112.     if (!contents)
  3113.     {
  3114.     return (WinInfoPtr) 0;
  3115.     }
  3116.  
  3117.     /*Add in an icon corral*/
  3118.     corral = NewIconCorral(visCorralClass,
  3119.         MINORBORDER, VWINPANELWIDTH - MINORBORDER, 
  3120.         MINORBORDER,
  3121.         VWINHEIGHT - MINORBORDER,
  3122.         BARRIGHT + BARBOTTOM);
  3123.  
  3124.     if (!corral)
  3125.     {
  3126.     return (WinInfoPtr) 0;
  3127.     }
  3128.     SetVar((ObjPtr) visWindow, CORRAL, corral);
  3129.  
  3130.     SetVar(corral, NAME, NewString("Space Contents"));
  3131.     SetVar(corral, HELPSTRING,
  3132.     NewString("This corral shows the objects and space controllers present \
  3133. in this visualization window.  You can drag new datasets from the datasets window \
  3134. into this corral to visualize them along with the other objects.  You can also \
  3135. drag in observer, renderer, clock, and lights icons.  There can only be one \
  3136. observer, renderer, and clock in a space, so dragging in these will replace the \
  3137. existing controller.\n"));
  3138.     SetVar(corral, STICKINESS, NewInt(STICKYLEFT + STICKYRIGHT +
  3139.                      STICKYBOTTOM + STICKYTOP));
  3140.     PrefixList(contents, corral);
  3141.     SetVar(corral, PARENT, panel);
  3142.  
  3143.     /*Splice the space to the corral*/
  3144.     SetVar(corral, SPACE, space);
  3145.     SetVar(space, CORRAL, corral);
  3146.  
  3147.     /*Add an observer*/
  3148.     AddControllerToSpace(NewObserver(), space, corral, NULLOBJ);
  3149.  
  3150.     /*Add a renderer*/
  3151.     AddControllerToSpace(NewRenderer(), space, corral, NULLOBJ);
  3152.  
  3153.     /*Add some lights*/
  3154. #ifdef GRAPHICS
  3155.     if (hasRGB)
  3156. #endif
  3157.     {
  3158.     lights = NewLights();
  3159.     runner = LISTOF(lights);
  3160.     while (runner)
  3161.     {
  3162.         AddControllerToSpace(runner -> thing, space, corral, NULLOBJ);
  3163.         runner = runner -> next;
  3164.     }
  3165.     }
  3166.  
  3167.     /*Add a clock*/
  3168.     AddControllerToSpace(NewClock(), space, corral, NULLOBJ);
  3169.  
  3170.     /*Add the method for PHSCologram*/
  3171.     SetMethod((ObjPtr) visWindow, PHSCSCREEN, WinPhscScreen);
  3172.  
  3173.     /*Add other vis methods*/
  3174.     SetMethod((ObjPtr) visWindow, SHOWFPCONTROLS, ShowFrontPanelControls);
  3175.     SetMethod((ObjPtr) visWindow, SHOWBPCONTROLS, ShowBackPanelControls);
  3176.     SetMethod((ObjPtr) visWindow, SHOWSPCONTROLS, ShowSpaceControls);
  3177.     SetMethod((ObjPtr) visWindow, TILEFULL, TileFullScreen);
  3178.     SetMethod((ObjPtr) visWindow, TILEVIDEO, TileVideoScreen);
  3179.  
  3180.     return visWindow;
  3181. }
  3182.  
  3183. ObjPtr FindSpace(win)
  3184. WinInfoPtr win;
  3185. /*Finds the space in win*/
  3186. {
  3187.     return GetVar((ObjPtr) win, SPACE);
  3188. }
  3189.  
  3190. ObjPtr FindObserver(win)
  3191. WinInfoPtr win;
  3192. /*Finds the observer in win*/
  3193. {
  3194.     ObjPtr space, retVal;
  3195.     retVal = GetVar((ObjPtr) win, REPOBJ);
  3196.     if (retVal && (IsObserver(retVal)))
  3197.     {
  3198.     return retVal;
  3199.     }
  3200.     space = FindSpace(win);
  3201.     if (space)
  3202.     {
  3203.     retVal = GetObjectVar("FindObserver", space, OBSERVER);
  3204.     }
  3205.     else
  3206.     {
  3207.     ReportError("FindObserver", "No space in window");
  3208.     }
  3209.     return retVal;
  3210. }
  3211.  
  3212. #ifdef PROTO
  3213. void RotateOrthoWindow(WinInfoPtr window, char axis, float amount)
  3214. #else
  3215. void RotateOrthoWindow(window, axis, amount)
  3216. WinInfoPtr window;
  3217. char axis;
  3218. float amount;
  3219. #endif
  3220. /*Rotates the observer in window about orthogonal axis axis by amount, and 
  3221.   stops continuous rotation.*/
  3222. {
  3223.     ObjPtr observer;
  3224.     real av[3];
  3225.  
  3226.     observer = FindObserver(window);
  3227.     if (!observer) return;
  3228.  
  3229.     switch(axis)
  3230.     {
  3231.     case 'x':
  3232.     case 'X':
  3233.         av[0] = 1.0;
  3234.         av[1] = 0.0;
  3235.         av[2] = 0.0;
  3236.         break;
  3237.     case 'y':
  3238.     case 'Y':
  3239.         av[0] = 0.0;
  3240.         av[1] = 1.0;
  3241.         av[2] = 0.0;
  3242.         break;
  3243.     case 'z':
  3244.     case 'Z':
  3245.         av[0] = 0.0;
  3246.         av[1] = 0.0;
  3247.         av[2] = 1.0;
  3248.         break;
  3249.     default:
  3250.         ReportError("RotateOrthoWindow", "Bad axis");
  3251.         return;
  3252.     }
  3253.     RotateObserver(observer, av, -amount * M_PI / 180.0, false);
  3254. }
  3255.  
  3256. static ObjPtr ChangeWindowToRGB(window, button)
  3257. WinInfoPtr window;
  3258. int button;
  3259. /*If button is 1, changes the color mode of window to RGB*/
  3260. {
  3261.     if (button == 1)
  3262.     {
  3263.     SelWindow(window);
  3264.     return ObjTrue;
  3265.     }
  3266.     else
  3267.     {
  3268.     return ObjFalse;
  3269.     }
  3270. }
  3271.  
  3272. ObjPtr SetVisWindowRGB(window)
  3273. ObjPtr window;
  3274. /*Deferred message to choose whether to make window RGB or not*/
  3275. {
  3276. #ifdef GRAPHICS
  3277.     char tempBuf[400];
  3278.     WinInfoPtr errWindow;
  3279.     WinInfoPtr spaceWindow;
  3280.  
  3281.     /*See if the window is already RGB*/
  3282.     spaceWindow = (WinInfoPtr) GetVar(window, SPACEWINDOW);
  3283.     if (!spaceWindow)
  3284.     {
  3285.     spaceWindow = (WinInfoPtr) window;
  3286.     }
  3287.     if (spaceWindow -> flags & WINRGB)
  3288.     {
  3289.     return;
  3290.     }
  3291.  
  3292.     if (!hasRGB)
  3293.     {
  3294.     return;
  3295.     }
  3296.  
  3297.     sprintf(tempBuf, "You will see no effects from this action in window %s \
  3298. until you change it to full color mode.  Would you like to change it now?",
  3299.     ((WinInfoPtr) window) -> winTitle);
  3300.  
  3301.     errWindow = AlertUser(UICAUTIONALERT, (WinInfoPtr) window, tempBuf,
  3302.     ChangeWindowToRGB, 2, "Cancel", "Change");
  3303.     SetVar((ObjPtr) errWindow, HELPSTRING,
  3304.     NewString("Visualization windows have two color modes: full color and color map.  \
  3305. Full color specifies full 24-bit RGB color.  Color map specifies mapped colors using a color \
  3306. table.  Some features, such as lighting, only work on windows set to full color mode.  \
  3307. If you click on the Change button, the affected window will automatically be set \
  3308. to this mode."));
  3309. #endif
  3310. }
  3311.  
  3312. void InitVisWindows()
  3313. /*Initializes the vis windows*/
  3314. {
  3315.     visualizeAsList = NewList();
  3316.     AddToReferenceList(visualizeAsList);
  3317.  
  3318.     visWindowClass = NewObject(objWindowClass, 0);
  3319.     AddToReferenceList(visWindowClass);
  3320.     SetVar(visWindowClass, CLASSID, NewInt(CLASS_VISWINDOW));
  3321.     SetVar(visWindowClass, HELPSTRING,
  3322.     NewString("This is a visualizaton window.  On the right is a panel which \
  3323. shows the visualization objects shown in the window, the controllers which \
  3324. affect the appearance of the object, and some buttons which affect the window \
  3325. as a whole or the selected icons.  If this panel is not shown, it can be brought \
  3326. back with the Toggle Panel item in the Window menu.  On the left is a \
  3327. 3-dimensional space in which \
  3328. the visualization object are shown.  There is one clear panel in front of the and \
  3329. one clear panel behind the space.  These panels are used to hold 2-dimensional \
  3330. objects such as clock readouts and text boxes, which can be created and modified \
  3331. with items in the Text menu.")); 
  3332. #if 0
  3333.     /*DIKEO I have decided to give up the RGB message*/
  3334.     SetMethod(visWindowClass, SETRGBMESSAGE, SetVisWindowRGB);
  3335. #endif
  3336.     SetMethod(visWindowClass, HIDEPANEL, HideVisWindowPanel);
  3337.     SetMethod(visWindowClass, SHOWPANEL, ShowVisWindowPanel);
  3338.     SetMethod(visWindowClass, RESHAPE, ReshapeVisWindow);
  3339.  
  3340.     spaceWindowClass = NewObject(objWindowClass, 0);
  3341.     AddToReferenceList(spaceWindowClass);
  3342.     SetVar(spaceWindowClass, HELPSTRING,
  3343.     NewString("This is a visualizaton window.  On the right is a panel which \
  3344. shows the visualization objects shown in the window, the controllers which \
  3345. affect the appearance of the object, and some buttons which affect the window \
  3346. as a whole or the selected icons.  If this panel is not shown, it can be brought \
  3347. back with the Toggle Panel item in the Window menu.  On the left is a \
  3348. 3-dimensional space in which \
  3349. the visualization object are shown.  There is one clear panel in front of the and \
  3350. one clear panel behind the space.  These panels are used to hold 2-dimensional \
  3351. objects such as clock readouts and text boxes, which can be created and modified \
  3352. with items in the Text menu.")); 
  3353.  
  3354.     /*Class for the corral in a vis window*/
  3355.     visCorralClass = NewObject(corralClass, 0);
  3356.     AddToReferenceList(visCorralClass);
  3357.     SetMethod(visCorralClass, DROPINCONTENTS, DropInVisCorral);
  3358. }
  3359.  
  3360. void KillVisWindows()
  3361. /*Kills the vis windows*/
  3362. {
  3363.     DeleteThing(visCorralClass);
  3364.     DeleteThing(spaceWindowClass);
  3365.     DeleteThing(visWindowClass);
  3366.     DeleteThing(visualizeAsList);
  3367. }
  3368.